Skip to content

Commit 85fe66e

Browse files
Skorpionmskotopes
andauthored
dap_link: fix application freezes, terminal is not open (#51)
Co-authored-by: あく <[email protected]>
1 parent 36e7e2a commit 85fe66e

File tree

4 files changed

+100
-62
lines changed

4 files changed

+100
-62
lines changed

dap_link/application.fam

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ App(
99
],
1010
stack_size=4 * 1024,
1111
fap_description="Enables use of Flipper as a debug probe for ARM devices, implements the CMSIS-DAP protocol",
12-
fap_version="1.0",
12+
fap_version="1.1",
1313
fap_icon="dap_link.png",
1414
fap_category="GPIO",
1515
fap_private_libs=[

dap_link/dap_link.c

Lines changed: 81 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,11 @@ void dap_app_get_state(DapApp* app, DapState* state) {
3636
#define DAP_PROCESS_THREAD_TICK 500
3737

3838
typedef enum {
39-
DapThreadEventStop = (1 << 0),
40-
} DapThreadEvent;
39+
DapEventStop = (1 << 0),
40+
} DapEvent;
4141

4242
void dap_thread_send_stop(FuriThread* thread) {
43-
furi_thread_flags_set(furi_thread_get_id(thread), DapThreadEventStop);
43+
furi_thread_flags_set(furi_thread_get_id(thread), DapEventStop);
4444
}
4545

4646
GpioPin flipper_dap_swclk_pin;
@@ -59,16 +59,16 @@ typedef struct {
5959
} DapPacket;
6060

6161
typedef enum {
62-
DAPThreadEventStop = DapThreadEventStop,
63-
DAPThreadEventRxV1 = (1 << 1),
64-
DAPThreadEventRxV2 = (1 << 2),
65-
DAPThreadEventUSBConnect = (1 << 3),
66-
DAPThreadEventUSBDisconnect = (1 << 4),
67-
DAPThreadEventApplyConfig = (1 << 5),
68-
DAPThreadEventAll = DAPThreadEventStop | DAPThreadEventRxV1 | DAPThreadEventRxV2 |
69-
DAPThreadEventUSBConnect | DAPThreadEventUSBDisconnect |
70-
DAPThreadEventApplyConfig,
71-
} DAPThreadEvent;
62+
DapThreadEventStop = DapEventStop,
63+
DapThreadEventRxV1 = (1 << 1),
64+
DapThreadEventRxV2 = (1 << 2),
65+
DapThreadEventUsbConnect = (1 << 3),
66+
DapThreadEventUsbDisconnect = (1 << 4),
67+
DapThreadEventApplyConfig = (1 << 5),
68+
DapThreadEventAll = DapThreadEventStop | DapThreadEventRxV1 | DapThreadEventRxV2 |
69+
DapThreadEventUsbConnect | DapThreadEventUsbDisconnect |
70+
DapThreadEventApplyConfig,
71+
} DapThreadEvent;
7272

7373
#define USB_SERIAL_NUMBER_LEN 16
7474
char usb_serial_number[USB_SERIAL_NUMBER_LEN] = {0};
@@ -81,22 +81,22 @@ const char* dap_app_get_serial(DapApp* app) {
8181
static void dap_app_rx1_callback(void* context) {
8282
furi_assert(context);
8383
FuriThreadId thread_id = (FuriThreadId)context;
84-
furi_thread_flags_set(thread_id, DAPThreadEventRxV1);
84+
furi_thread_flags_set(thread_id, DapThreadEventRxV1);
8585
}
8686

8787
static void dap_app_rx2_callback(void* context) {
8888
furi_assert(context);
8989
FuriThreadId thread_id = (FuriThreadId)context;
90-
furi_thread_flags_set(thread_id, DAPThreadEventRxV2);
90+
furi_thread_flags_set(thread_id, DapThreadEventRxV2);
9191
}
9292

9393
static void dap_app_usb_state_callback(bool state, void* context) {
9494
furi_assert(context);
9595
FuriThreadId thread_id = (FuriThreadId)context;
9696
if(state) {
97-
furi_thread_flags_set(thread_id, DAPThreadEventUSBConnect);
97+
furi_thread_flags_set(thread_id, DapThreadEventUsbConnect);
9898
} else {
99-
furi_thread_flags_set(thread_id, DAPThreadEventUSBDisconnect);
99+
furi_thread_flags_set(thread_id, DapThreadEventUsbDisconnect);
100100
}
101101
}
102102

@@ -207,39 +207,39 @@ static int32_t dap_process(void* p) {
207207
// work
208208
uint32_t events;
209209
while(1) {
210-
events = furi_thread_flags_wait(DAPThreadEventAll, FuriFlagWaitAny, FuriWaitForever);
210+
events = furi_thread_flags_wait(DapThreadEventAll, FuriFlagWaitAny, FuriWaitForever);
211211

212212
if(!(events & FuriFlagError)) {
213-
if(events & DAPThreadEventRxV1) {
213+
if(events & DapThreadEventRxV1) {
214214
dap_app_process_v1();
215215
dap_state->dap_counter++;
216216
dap_state->dap_version = DapVersionV1;
217217
}
218218

219-
if(events & DAPThreadEventRxV2) {
219+
if(events & DapThreadEventRxV2) {
220220
dap_app_process_v2();
221221
dap_state->dap_counter++;
222222
dap_state->dap_version = DapVersionV2;
223223
}
224224

225-
if(events & DAPThreadEventUSBConnect) {
225+
if(events & DapThreadEventUsbConnect) {
226226
dap_state->usb_connected = true;
227227
}
228228

229-
if(events & DAPThreadEventUSBDisconnect) {
229+
if(events & DapThreadEventUsbDisconnect) {
230230
dap_state->usb_connected = false;
231231
dap_state->dap_version = DapVersionUnknown;
232232
}
233233

234-
if(events & DAPThreadEventApplyConfig) {
234+
if(events & DapThreadEventApplyConfig) {
235235
if(swd_pins_prev != app->config.swd_pins) {
236236
dap_deinit_gpio(swd_pins_prev);
237237
swd_pins_prev = app->config.swd_pins;
238238
dap_init_gpio(swd_pins_prev);
239239
}
240240
}
241241

242-
if(events & DAPThreadEventStop) {
242+
if(events & DapThreadEventStop) {
243243
break;
244244
}
245245
}
@@ -257,14 +257,20 @@ static int32_t dap_process(void* p) {
257257
/***************************************************************************/
258258

259259
typedef enum {
260-
CDCThreadEventStop = DapThreadEventStop,
261-
CDCThreadEventUARTRx = (1 << 1),
262-
CDCThreadEventCDCRx = (1 << 2),
263-
CDCThreadEventCDCConfig = (1 << 3),
264-
CDCThreadEventApplyConfig = (1 << 4),
265-
CDCThreadEventAll = CDCThreadEventStop | CDCThreadEventUARTRx | CDCThreadEventCDCRx |
266-
CDCThreadEventCDCConfig | CDCThreadEventApplyConfig,
267-
} CDCThreadEvent;
260+
CdcThreadEventStop = DapEventStop,
261+
CdcThreadEventUartRx = (1 << 1),
262+
CdcThreadEventCdcRx = (1 << 2),
263+
CdcThreadEventCdcConfig = (1 << 3),
264+
CdcThreadEventApplyConfig = (1 << 4),
265+
CdcThreadEventCdcDtrHigh = (1 << 5),
266+
CdcThreadEventCdcDtrLow = (1 << 6),
267+
CdcThreadEventCdcTxComplete = (1 << 7),
268+
269+
CdcThreadEventAll = CdcThreadEventStop | CdcThreadEventUartRx | CdcThreadEventCdcRx |
270+
CdcThreadEventCdcConfig | CdcThreadEventApplyConfig |
271+
CdcThreadEventCdcDtrHigh | CdcThreadEventCdcDtrLow |
272+
CdcThreadEventCdcTxComplete,
273+
} CdcThreadEvent;
268274

269275
typedef struct {
270276
FuriStreamBuffer* rx_stream;
@@ -278,24 +284,36 @@ static void cdc_uart_irq_cb(UartIrqEvent ev, uint8_t data, void* ctx) {
278284

279285
if(ev == UartIrqEventRXNE) {
280286
furi_stream_buffer_send(app->rx_stream, &data, 1, 0);
281-
furi_thread_flags_set(app->thread_id, CDCThreadEventUARTRx);
287+
furi_thread_flags_set(app->thread_id, CdcThreadEventUartRx);
282288
}
283289
}
284290

285291
static void cdc_usb_rx_callback(void* context) {
286292
CDCProcess* app = context;
287-
furi_thread_flags_set(app->thread_id, CDCThreadEventCDCRx);
293+
furi_thread_flags_set(app->thread_id, CdcThreadEventCdcRx);
294+
}
295+
296+
static void cdc_usb_tx_complete_callback(void* context) {
297+
CDCProcess* app = context;
298+
furi_thread_flags_set(app->thread_id, CdcThreadEventCdcTxComplete);
288299
}
289300

290301
static void cdc_usb_control_line_callback(uint8_t state, void* context) {
291-
UNUSED(context);
292-
UNUSED(state);
302+
CDCProcess* app = context;
303+
// bit 0: DTR state, bit 1: RTS state
304+
bool dtr = state & (1 << 0);
305+
306+
if(dtr == true) {
307+
furi_thread_flags_set(app->thread_id, CdcThreadEventCdcDtrHigh);
308+
} else {
309+
furi_thread_flags_set(app->thread_id, CdcThreadEventCdcDtrLow);
310+
}
293311
}
294312

295313
static void cdc_usb_config_callback(struct usb_cdc_line_coding* config, void* context) {
296314
CDCProcess* app = context;
297315
app->line_coding = *config;
298-
furi_thread_flags_set(app->thread_id, CDCThreadEventCDCConfig);
316+
furi_thread_flags_set(app->thread_id, CdcThreadEventCdcConfig);
299317
}
300318

301319
static FuriHalUartId cdc_init_uart(
@@ -350,7 +368,7 @@ static void cdc_deinit_uart(DapUartType type) {
350368
}
351369
}
352370

353-
static int32_t cdc_process(void* p) {
371+
static int32_t dap_cdc_process(void* p) {
354372
DapApp* dap_app = p;
355373
DapState* dap_state = &(dap_app->state);
356374

@@ -372,15 +390,18 @@ static int32_t cdc_process(void* p) {
372390

373391
dap_cdc_usb_set_context(app);
374392
dap_cdc_usb_set_rx_callback(cdc_usb_rx_callback);
393+
dap_cdc_usb_set_tx_complete_callback(cdc_usb_tx_complete_callback);
375394
dap_cdc_usb_set_control_line_callback(cdc_usb_control_line_callback);
376395
dap_cdc_usb_set_config_callback(cdc_usb_config_callback);
377396

397+
bool cdc_connect = false;
398+
378399
uint32_t events;
379400
while(1) {
380-
events = furi_thread_flags_wait(CDCThreadEventAll, FuriFlagWaitAny, FuriWaitForever);
401+
events = furi_thread_flags_wait(CdcThreadEventAll, FuriFlagWaitAny, FuriWaitForever);
381402

382403
if(!(events & FuriFlagError)) {
383-
if(events & CDCThreadEventCDCConfig) {
404+
if(events & CdcThreadEventCdcConfig) {
384405
if(dap_state->cdc_baudrate != app->line_coding.dwDTERate) {
385406
dap_state->cdc_baudrate = app->line_coding.dwDTERate;
386407
if(dap_state->cdc_baudrate > 0) {
@@ -389,25 +410,26 @@ static int32_t cdc_process(void* p) {
389410
}
390411
}
391412

392-
if(events & CDCThreadEventUARTRx) {
413+
if(events & (CdcThreadEventUartRx | CdcThreadEventCdcTxComplete)) {
393414
size_t len =
394415
furi_stream_buffer_receive(app->rx_stream, rx_buffer, rx_buffer_size, 0);
395-
396-
if(len > 0) {
397-
dap_cdc_usb_tx(rx_buffer, len);
416+
if(cdc_connect) {
417+
if(len > 0) {
418+
dap_cdc_usb_tx(rx_buffer, len);
419+
}
420+
dap_state->cdc_rx_counter += len;
398421
}
399-
dap_state->cdc_rx_counter += len;
400422
}
401423

402-
if(events & CDCThreadEventCDCRx) {
424+
if(events & CdcThreadEventCdcRx) {
403425
size_t len = dap_cdc_usb_rx(rx_buffer, rx_buffer_size);
404426
if(len > 0) {
405427
furi_hal_uart_tx(app->uart_id, rx_buffer, len);
406428
}
407429
dap_state->cdc_tx_counter += len;
408430
}
409431

410-
if(events & CDCThreadEventApplyConfig) {
432+
if(events & CdcThreadEventApplyConfig) {
411433
if(uart_pins_prev != dap_app->config.uart_pins ||
412434
uart_swap_prev != dap_app->config.uart_swap) {
413435
cdc_deinit_uart(uart_pins_prev);
@@ -422,9 +444,15 @@ static int32_t cdc_process(void* p) {
422444
}
423445
}
424446

425-
if(events & CDCThreadEventStop) {
447+
if(events & CdcThreadEventStop) {
426448
break;
427449
}
450+
if(events & CdcThreadEventCdcDtrHigh) {
451+
cdc_connect = true;
452+
}
453+
if(events & CdcThreadEventCdcDtrLow) {
454+
cdc_connect = false;
455+
}
428456
}
429457
}
430458

@@ -442,9 +470,9 @@ static int32_t cdc_process(void* p) {
442470

443471
static DapApp* dap_app_alloc() {
444472
DapApp* dap_app = malloc(sizeof(DapApp));
445-
dap_app->dap_thread = furi_thread_alloc_ex("DAP Process", 1024, dap_process, dap_app);
446-
dap_app->cdc_thread = furi_thread_alloc_ex("DAP CDC", 1024, cdc_process, dap_app);
447-
dap_app->gui_thread = furi_thread_alloc_ex("DAP GUI", 1024, dap_gui_thread, dap_app);
473+
dap_app->dap_thread = furi_thread_alloc_ex("DapProcess", 1024, dap_process, dap_app);
474+
dap_app->cdc_thread = furi_thread_alloc_ex("DapCdcProcess", 1024, dap_cdc_process, dap_app);
475+
dap_app->gui_thread = furi_thread_alloc_ex("DapGui", 1024, dap_gui_thread, dap_app);
448476
return dap_app;
449477
}
450478

@@ -472,8 +500,8 @@ void dap_app_connect_jtag() {
472500

473501
void dap_app_set_config(DapApp* app, DapConfig* config) {
474502
app->config = *config;
475-
furi_thread_flags_set(furi_thread_get_id(app->dap_thread), DAPThreadEventApplyConfig);
476-
furi_thread_flags_set(furi_thread_get_id(app->cdc_thread), CDCThreadEventApplyConfig);
503+
furi_thread_flags_set(furi_thread_get_id(app->dap_thread), DapThreadEventApplyConfig);
504+
furi_thread_flags_set(furi_thread_get_id(app->cdc_thread), CdcThreadEventApplyConfig);
477505
}
478506

479507
DapConfig* dap_app_get_config(DapApp* app) {

dap_link/usb/dap_v2_usb.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,7 @@ typedef struct {
449449
DapRxCallback rx_callback_v1;
450450
DapRxCallback rx_callback_v2;
451451
DapRxCallback rx_callback_cdc;
452+
DapRxCallback tx_complete_cdc;
452453
DapCDCControlLineCallback control_line_callback_cdc;
453454
DapCDCConfigCallback config_callback_cdc;
454455
void* context;
@@ -522,15 +523,15 @@ int32_t dap_v2_usb_tx(uint8_t* buffer, uint8_t size) {
522523
int32_t dap_cdc_usb_tx(uint8_t* buffer, uint8_t size) {
523524
if((dap_state.semaphore_cdc == NULL) || (dap_state.connected == false)) return 0;
524525

525-
furi_check(furi_semaphore_acquire(dap_state.semaphore_cdc, FuriWaitForever) == FuriStatusOk);
526-
527-
if(dap_state.connected) {
528-
int32_t len = usbd_ep_write(dap_state.usb_dev, HID_EP_IN | DAP_CDC_EP_SEND, buffer, size);
529-
furi_console_log_printf("cdc tx %ld", len);
530-
return len;
531-
} else {
532-
return 0;
526+
if(furi_semaphore_acquire(dap_state.semaphore_cdc, 100) == FuriStatusOk) {
527+
if(dap_state.connected) {
528+
int32_t len =
529+
usbd_ep_write(dap_state.usb_dev, HID_EP_IN | DAP_CDC_EP_SEND, buffer, size);
530+
furi_console_log_printf("cdc tx %ld", len);
531+
return len;
532+
}
533533
}
534+
return 0;
534535
}
535536

536537
void dap_v1_usb_set_rx_callback(DapRxCallback callback) {
@@ -545,6 +546,10 @@ void dap_cdc_usb_set_rx_callback(DapRxCallback callback) {
545546
dap_state.rx_callback_cdc = callback;
546547
}
547548

549+
void dap_cdc_usb_set_tx_complete_callback(DapRxCallback callback) {
550+
dap_state.tx_complete_cdc = callback;
551+
}
552+
548553
void dap_cdc_usb_set_control_line_callback(DapCDCControlLineCallback callback) {
549554
dap_state.control_line_callback_cdc = callback;
550555
}
@@ -735,6 +740,9 @@ static void cdc_txrx_ep_callback(usbd_device* dev, uint8_t event, uint8_t ep) {
735740
switch(event) {
736741
case usbd_evt_eptx:
737742
furi_semaphore_release(dap_state.semaphore_cdc);
743+
if(dap_state.tx_complete_cdc != NULL) {
744+
dap_state.tx_complete_cdc(dap_state.context_cdc);
745+
}
738746
furi_console_log_printf("cdc tx complete");
739747
break;
740748
case usbd_evt_eprx:

dap_link/usb/dap_v2_usb.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ size_t dap_cdc_usb_rx(uint8_t* buffer, size_t size);
3636

3737
void dap_cdc_usb_set_rx_callback(DapRxCallback callback);
3838

39+
void dap_cdc_usb_set_tx_complete_callback(DapRxCallback callback);
40+
3941
void dap_cdc_usb_set_control_line_callback(DapCDCControlLineCallback callback);
4042

4143
void dap_cdc_usb_set_config_callback(DapCDCConfigCallback callback);

0 commit comments

Comments
 (0)