1 #include "cybt_platform_config.h"
2
3 #ifdef ENABLE_DEBUG_UART
4
5 #define CYHAL_UART_DMA_ENABLE_RX FALSE
6 #define CYHAL_UART_DMA_ENABLE_TX FALSE
7
8 #include "cyhal_uart.h"
9 #include "cyabs_rtos.h"
10 #include "cybsp_types.h"
11 #include "cybt_platform_task.h"
12 #include "cybt_debug_uart.h"
13 #include "cybt_platform_interface.h"
14 #include "wiced_memory.h"
15
16 extern void host_stack_mutex_lock(void * p_lock_context);
17 extern void host_stack_mutex_unlock(void * p_lock_context);
18
19 #define HCI_WICED_PKT 0x19
20 #define HCI_WICED_OVERHEAD 5 // Type (1), opcode (2) and length (2)
21
22 #ifndef DISABLE_TX_TASK
23 #define BT_TASK_NAME_DEBUG_UART_TX "TX_CYBT_DEBUG_UART_Task"
24 #define DEBUG_UART_TX_TASK_STACK_SIZE (0x1700)
25 #define DEBUG_UART_TX_TASK_QUEUE_COUNT (50)
26 #define DEBUG_UART_TX_QUEUE_ITEM_SIZE (sizeof(void *))
27 #define DEBUG_UART_TX_TASK_QUEUE cybt_debug_uart_tx_queue
28 #define DEBUG_UART_TX_TASK_PRIORITY (CY_RTOS_PRIORITY_ABOVENORMAL)
29
30 #ifndef DEBUG_UART_MEMORY_SIZE
31 #define DEBUG_UART_MEMORY_SIZE (6144)
32 #endif
33
34 wiced_bt_heap_t *debug_task_heap = NULL;
35 #endif
36
37 #define BT_TASK_NAME_DEBUG_UART_RX "RX_CYBT_DEBUG_UART_Task"
38
39 #define DEBUG_UART_RX_TASK_STACK_SIZE (0x1700)
40
41 #define DEBUG_UART_RX_TASK_PRIORITY (CY_RTOS_PRIORITY_ABOVENORMAL)
42
43 #define WICED_HDR_SZ 5
44
45 #define MAX_RX_DATA_LEN 1000
46
47 #define HCI_CONTROL_GROUP_DEVICE 0x00
48 #define HCI_CONTROL_EVENT_WICED_TRACE ( ( HCI_CONTROL_GROUP_DEVICE << 8 ) | 0x02 ) /* WICED trace packet */
49 #define HCI_CONTROL_EVENT_HCI_TRACE ( ( HCI_CONTROL_GROUP_DEVICE << 8 ) | 0x03 ) /* Bluetooth protocol trace */
50 #define INVALID_TYPE 0xFF
51 #define GENERIC_TYPE 0x00
52
53 enum
54 {
55 HEADER_PHASE = 0,
56 DATA_PHASE
57 };
58
59 typedef struct
60 {
61 bool inited;
62 cyhal_uart_t hal_obj;
63 #ifndef DISABLE_TX_TASK
64 cy_semaphore_t tx_complete;
65 cy_semaphore_t tx_ready;
66 cy_mutex_t tx_heap_lock;
67 #endif
68 cy_semaphore_t rx_complete;
69 cy_mutex_t tx_atomic;
70 } hci_uart_cb_t;
71
72 typedef struct
73 {
74 uint16_t length;
75 uint8_t *data;
76 }recv_data_t;
77
78 hci_uart_cb_t cy_trans_uart;
79 #ifndef DISABLE_TX_TASK
80 cy_queue_t cybt_debug_uart_tx_queue;
81 cy_thread_t cybt_debug_uart_tx_task;
82 #endif
83 cy_thread_t cybt_debug_uart_rx_task;
84
85 /*
86 * Global variable declarations
87 */
88 uint8_t wiced_rx_cmd[MAX_RX_DATA_LEN+WICED_HDR_SZ]; //RX command pool.
89
90
91 static bool trans_setup = false;
92 static cybt_debug_uart_data_handler_t p_app_rx_cmd_handler = NULL;
93 volatile bool rx_done = false;
94
95 static bool cybt_debug_uart_setup = false;
96
97 #ifdef DISABLE_TX_TASK
98
99 static cybt_result_t cybt_trans_blocking_write (uint8_t type, uint16_t opcode, uint16_t data_size, uint8_t *p_data);
100
101 #else
102
103 static cybt_result_t cybt_enqueue_tx_data (uint16_t type, uint16_t op,uint16_t length, uint8_t* p_data);
104
105 BTSTACK_PORTING_SECTION_BEGIN
debug_heap_mutex_lock(void * p_lock_context)106 static void debug_heap_mutex_lock(void * p_lock_context)
107 {
108 cy_rtos_get_mutex(p_lock_context, CY_RTOS_NEVER_TIMEOUT);
109 }
110 BTSTACK_PORTING_SECTION_END
111
112 BTSTACK_PORTING_SECTION_BEGIN
debug_heap_mutex_unlock(void * p_lock_context)113 static void debug_heap_mutex_unlock(void * p_lock_context)
114 {
115 cy_rtos_set_mutex(p_lock_context);
116 }
117 BTSTACK_PORTING_SECTION_END
118
119 BTSTACK_PORTING_SECTION_BEGIN
cybt_platform_debug_task_mempool_alloc(uint32_t req_size)120 static void *cybt_platform_debug_task_mempool_alloc(uint32_t req_size)
121 {
122 void *p_mem_block;
123
124 if (NULL == debug_task_heap)
125 {
126 return NULL;
127 }
128
129 p_mem_block = (void *) wiced_bt_get_buffer_from_heap(debug_task_heap, req_size);
130
131 return p_mem_block;
132 }
133 BTSTACK_PORTING_SECTION_END
134
135 BTSTACK_PORTING_SECTION_BEGIN
cybt_memcpy(void * dest,const void * src,size_t len)136 static void *cybt_memcpy (void *dest, const void *src, size_t len)
137 {
138 uint8_t *pDest = (uint8_t*)dest;
139 const uint8_t *pSrc = (const uint8_t*)src;
140 while(len--)
141 {
142 *pDest++ = *pSrc++;
143 }
144 return dest;
145 }
146 BTSTACK_PORTING_SECTION_END
147
148 BTSTACK_PORTING_SECTION_BEGIN
cybt_platform_debug_task_mempool_free(void * p_mem_block)149 static void cybt_platform_debug_task_mempool_free(void *p_mem_block)
150 {
151 wiced_bt_free_buffer((wiced_bt_buffer_t *) p_mem_block);
152 }
153 BTSTACK_PORTING_SECTION_END
154
155 BTSTACK_PORTING_SECTION_BEGIN
cybt_enqueue_tx_data(uint16_t type,uint16_t opcode,uint16_t length,uint8_t * p_data)156 static cybt_result_t cybt_enqueue_tx_data (uint16_t type, uint16_t opcode, uint16_t length, uint8_t* p_data)
157 {
158 uint8_t *p_buf = NULL, *p_buf_start = NULL;
159 cy_rslt_t result = CYBT_ERR_GENERIC;
160 size_t count = 0;
161
162 if (trans_setup == false)
163 return CYBT_ERR_GENERIC;
164
165 result = cy_rtos_get_semaphore(&cy_trans_uart.tx_ready, CY_RTOS_NEVER_TIMEOUT, false);
166
167 if (CY_RSLT_SUCCESS != result)
168 return CYBT_ERR_GENERIC;
169
170 result = cy_rtos_count_queue(&DEBUG_UART_TX_TASK_QUEUE, &count);
171 if ( (result != CY_RSLT_SUCCESS) || (count == DEBUG_UART_TX_TASK_QUEUE_COUNT))
172 {
173 cy_rtos_set_semaphore(&cy_trans_uart.tx_ready, false);
174 return CYBT_ERR_QUEUE_FULL;
175 }
176
177 p_buf = cybt_platform_debug_task_mempool_alloc(length + HCI_WICED_OVERHEAD + 1);
178 if (p_buf == NULL)
179 {
180 cy_rtos_set_semaphore(&cy_trans_uart.tx_ready, false);
181 return CYBT_ERR_OUT_OF_MEMORY;
182 }
183 p_buf_start = p_buf;
184
185 *p_buf++ = HCI_WICED_PKT;
186
187 if ( (type != INVALID_TYPE) || (opcode == HCI_CONTROL_EVENT_HCI_TRACE) )
188 {
189 *p_buf++ = (uint8_t)(HCI_CONTROL_EVENT_HCI_TRACE);
190 *p_buf++ = (uint8_t)(HCI_CONTROL_EVENT_HCI_TRACE >> 8);
191 *p_buf++ = (uint8_t)(length + 1);
192 *p_buf++ = (uint8_t)((length + 1) >> 8);
193 *p_buf++ = type;
194 }
195 else
196 {
197 *p_buf++ = (uint8_t)(opcode);
198 *p_buf++ = (uint8_t)(opcode >> 8);
199 *p_buf++ = (uint8_t)(length);
200 *p_buf++ = (uint8_t)(length >> 8);
201 }
202
203 cybt_memcpy (p_buf, p_data, length);
204
205 result = cy_rtos_put_queue (&DEBUG_UART_TX_TASK_QUEUE, (void *) &p_buf_start, 0, false);
206
207 if (CY_RSLT_SUCCESS != result)
208 cybt_platform_debug_task_mempool_free((void *)p_buf_start);
209
210 cy_rtos_set_semaphore(&cy_trans_uart.tx_ready, false);
211 return CYBT_SUCCESS;
212 }
213 BTSTACK_PORTING_SECTION_END
214
215 BTSTACK_PORTING_SECTION_BEGIN
cybt_debug_uart_send_wiced_hci_buf(void * p_buf)216 cybt_result_t cybt_debug_uart_send_wiced_hci_buf (void *p_buf)
217 {
218 cy_rslt_t result = CYBT_ERR_GENERIC;
219 size_t count = 0;
220
221 if (trans_setup == false)
222 return CYBT_ERR_GENERIC;
223
224 result = cy_rtos_get_semaphore(&cy_trans_uart.tx_ready, CY_RTOS_NEVER_TIMEOUT, false);
225
226 if (CY_RSLT_SUCCESS != result)
227 return CYBT_ERR_GENERIC;
228
229 result = cy_rtos_count_queue(&DEBUG_UART_TX_TASK_QUEUE, &count);
230 if ( (result != CY_RSLT_SUCCESS) || (count == DEBUG_UART_TX_TASK_QUEUE_COUNT))
231 {
232 cy_rtos_set_semaphore (&cy_trans_uart.tx_ready, false);
233 return CYBT_ERR_QUEUE_FULL;
234 }
235
236 result = cy_rtos_put_queue (&DEBUG_UART_TX_TASK_QUEUE, (void *) &p_buf, 0, false);
237
238 cy_rtos_set_semaphore(&cy_trans_uart.tx_ready, false);
239 return (cybt_result_t)result;
240 }
241 BTSTACK_PORTING_SECTION_END
242
243 BTSTACK_PORTING_SECTION_BEGIN
cybt_debug_tx_task(void * arg)244 static void cybt_debug_tx_task(void *arg)
245 {
246 cy_rslt_t result;
247 uint8_t *p_data;
248 size_t data_len;
249
250 while (1)
251 {
252 p_data = NULL;
253 result = cy_rtos_get_queue(&DEBUG_UART_TX_TASK_QUEUE,
254 (void *)&p_data,
255 CY_RTOS_NEVER_TIMEOUT,
256 false
257 );
258
259 if (CY_RSLT_SUCCESS != result || NULL == p_data)
260 continue;
261
262 // Payload is in bytes 3 and 4
263 data_len = ((p_data[4] << 8) | p_data[3]);
264
265 result = cyhal_uart_write_async (&cy_trans_uart.hal_obj, p_data, data_len + HCI_WICED_OVERHEAD);
266
267 if (CY_RSLT_SUCCESS == result)
268 cy_rtos_get_semaphore (&cy_trans_uart.tx_complete, CY_RTOS_NEVER_TIMEOUT, false);
269
270 cybt_platform_debug_task_mempool_free (p_data);
271 }
272 }
273 BTSTACK_PORTING_SECTION_END
274
275 #endif
276
277 BTSTACK_PORTING_SECTION_BEGIN
cybt_debug_rx_task(void * arg)278 static void cybt_debug_rx_task(void *arg)
279 {
280 cy_rslt_t result;
281 volatile uint32_t numAvailable = 0;
282 volatile size_t expectedlength = 0;
283 volatile uint32_t head=0,phase=HEADER_PHASE,data_counter=0;
284
285 while(1)
286 {
287 result = cy_rtos_get_semaphore(&cy_trans_uart.rx_complete, CY_RTOS_NEVER_TIMEOUT, false);
288
289 if (result != CY_RSLT_SUCCESS)
290 continue;
291
292 numAvailable = 0;
293 expectedlength = ( phase == DATA_PHASE ) ? ( data_counter ) : ( WICED_HDR_SZ );
294 if (!rx_done)
295 {
296 if (CYHAL_UART_DMA_ENABLE_RX == TRUE)
297 {
298 cyhal_uart_enable_event(&cy_trans_uart.hal_obj, CYHAL_UART_IRQ_RX_DONE, 4u, true);
299 cyhal_uart_read_async(&cy_trans_uart.hal_obj, wiced_rx_cmd + head, expectedlength);
300 continue;
301 }
302 else
303 {
304 numAvailable = cyhal_uart_readable(&cy_trans_uart.hal_obj);
305 if (numAvailable >= expectedlength)
306 {
307 cyhal_uart_read(&cy_trans_uart.hal_obj, wiced_rx_cmd + head, (size_t *)&expectedlength);
308 numAvailable -= expectedlength;
309 }
310 else
311 {
312 cyhal_uart_enable_event(&cy_trans_uart.hal_obj, CYHAL_UART_IRQ_RX_DONE, CYHAL_ISR_PRIORITY_DEFAULT, true);
313 cyhal_uart_read_async(&cy_trans_uart.hal_obj, wiced_rx_cmd + head, expectedlength);
314 continue;
315 }
316 }
317 }
318
319 if (numAvailable == 0)
320 {
321 rx_done = false;
322 cyhal_uart_enable_event(&cy_trans_uart.hal_obj, CYHAL_UART_IRQ_RX_NOT_EMPTY, CYHAL_ISR_PRIORITY_DEFAULT, true);
323 }
324
325 switch (phase)
326 {
327 case HEADER_PHASE:
328 if(wiced_rx_cmd[0] != HCI_WICED_PKT)
329 {
330 head=0x0;
331 break;
332 }
333 data_counter = ( wiced_rx_cmd[3] | (uint32_t)(wiced_rx_cmd[4])<<8);
334 head = WICED_HDR_SZ;
335 phase = DATA_PHASE;
336 break;
337 case DATA_PHASE:
338 data_counter -= expectedlength;
339 head += expectedlength;
340 break;
341 }
342
343 if ( (data_counter == 0) && (head != 0) && (p_app_rx_cmd_handler != NULL) )
344 {
345 phase = HEADER_PHASE;
346 host_stack_mutex_lock(NULL);
347 p_app_rx_cmd_handler(wiced_rx_cmd+1, head-1);
348 host_stack_mutex_unlock(NULL);
349 head = 0;
350 }
351
352 if (numAvailable != 0)
353 {
354 // re-enter the loop if data is available
355 cy_rtos_set_semaphore(&cy_trans_uart.rx_complete, true);
356 continue;
357 }
358 }
359 }
360 BTSTACK_PORTING_SECTION_END
361
cybt_init_debug_trans_task(void)362 cybt_result_t cybt_init_debug_trans_task(void)
363 {
364 cy_rslt_t result;
365
366 if(true == trans_setup)
367 return CYBT_SUCCESS;
368
369 #ifndef DISABLE_TX_TASK
370 {
371 void *p_heap_mem = NULL;
372
373 cy_rtos_init_mutex(&cy_trans_uart.tx_heap_lock);
374
375 wiced_bt_lock_t lock = {
376 .p_lock_context = &cy_trans_uart.tx_heap_lock,
377 .pf_lock_func = debug_heap_mutex_lock,
378 .pf_unlock_func = debug_heap_mutex_unlock
379 };
380
381 p_heap_mem = (wiced_bt_heap_t *)cybt_platform_malloc(DEBUG_UART_MEMORY_SIZE);
382 if (p_heap_mem == NULL)
383 return CYBT_ERR_OUT_OF_MEMORY;
384
385 debug_task_heap = wiced_bt_create_heap("CYBT_DEBUG_TASK_POOL",
386 p_heap_mem,
387 DEBUG_UART_MEMORY_SIZE,
388 &lock,
389 FALSE
390 );
391
392 result = cy_rtos_init_queue(&DEBUG_UART_TX_TASK_QUEUE,
393 DEBUG_UART_TX_TASK_QUEUE_COUNT,
394 DEBUG_UART_TX_QUEUE_ITEM_SIZE
395 );
396 if (result != CY_RSLT_SUCCESS)
397 return CYBT_ERR_INIT_QUEUE_FAILED;
398
399 result = cy_rtos_create_thread(&cybt_debug_uart_tx_task,
400 cybt_debug_tx_task,
401 BT_TASK_NAME_DEBUG_UART_TX,
402 NULL,
403 DEBUG_UART_TX_TASK_STACK_SIZE,
404 DEBUG_UART_TX_TASK_PRIORITY,
405 (cy_thread_arg_t) NULL
406 );
407 if (result != CY_RSLT_SUCCESS)
408 return CYBT_ERR_CREATE_TASK_FAILED;
409 }
410 #endif
411
412 result = cy_rtos_create_thread(&cybt_debug_uart_rx_task,
413 cybt_debug_rx_task,
414 BT_TASK_NAME_DEBUG_UART_RX,
415 NULL,
416 DEBUG_UART_RX_TASK_STACK_SIZE,
417 DEBUG_UART_RX_TASK_PRIORITY,
418 (cy_thread_arg_t) NULL
419 );
420
421 if (result != CY_RSLT_SUCCESS)
422 return CYBT_ERR_CREATE_TASK_FAILED;
423
424 trans_setup = true;
425 return CYBT_SUCCESS;
426 }
427
428 #ifndef DISABLE_TX_TASK
cybt_uart_tx_irq(void)429 static void cybt_uart_tx_irq(void)
430 {
431 cy_rtos_set_semaphore(&cy_trans_uart.tx_complete, true);
432 }
433 #endif
434
435 BTSTACK_PORTING_SECTION_BEGIN
cybt_uart_irq_handler_(void * handler_arg,cyhal_uart_event_t event)436 static void cybt_uart_irq_handler_(void *handler_arg, cyhal_uart_event_t event)
437 {
438 switch(event)
439 {
440 case CYHAL_UART_IRQ_RX_NOT_EMPTY:
441 cyhal_uart_enable_event(&cy_trans_uart.hal_obj, CYHAL_UART_IRQ_RX_NOT_EMPTY, CYHAL_ISR_PRIORITY_DEFAULT, false);
442 cy_rtos_set_semaphore(&cy_trans_uart.rx_complete, true);
443 break;
444 case CYHAL_UART_IRQ_RX_DONE:
445 rx_done = true;
446 cyhal_uart_enable_event(&cy_trans_uart.hal_obj, CYHAL_UART_IRQ_RX_DONE, CYHAL_ISR_PRIORITY_DEFAULT, false);
447 cy_rtos_set_semaphore(&cy_trans_uart.rx_complete, true);
448 break;
449 #ifndef DISABLE_TX_TASK
450 case CYHAL_UART_IRQ_TX_DONE:
451 cybt_uart_tx_irq();
452 break;
453 #endif
454 default:
455 break;
456 }
457 }
458 BTSTACK_PORTING_SECTION_END
459
cybt_debug_uart_init(cybt_debug_uart_config_t * config,cybt_debug_uart_data_handler_t p_data_handler)460 cybt_result_t cybt_debug_uart_init(cybt_debug_uart_config_t *config, cybt_debug_uart_data_handler_t p_data_handler)
461 {
462 const cyhal_uart_cfg_t uart_config =
463 {
464 .data_bits = 8,
465 .stop_bits = 1,
466 .parity = CYHAL_UART_PARITY_NONE,
467 .rx_buffer = NULL,
468 .rx_buffer_size = 0,
469 };
470 uint16_t enable_irq_event = (CYHAL_UART_IRQ_TX_DONE
471 | CYHAL_UART_IRQ_RX_NOT_EMPTY
472 );
473 cy_rslt_t result = CY_RSLT_SUCCESS;
474
475 if(!cybt_debug_uart_setup)
476 memset(&cy_trans_uart, 0, sizeof(hci_uart_cb_t));
477 else
478 memset(&cy_trans_uart.hal_obj, 0, sizeof(cyhal_uart_t));
479
480 if (!config)
481 {
482 return CYBT_ERR_BADARG;
483 }
484
485 #if (CYHAL_API_VERSION >= 2)
486 {
487 /* init and setting flow control */
488 result = cyhal_uart_init(&cy_trans_uart.hal_obj,
489 config->uart_tx_pin,
490 config->uart_rx_pin,
491 config->uart_cts_pin,
492 config->uart_rts_pin,
493 NULL,
494 &uart_config
495 );
496 }
497 #else // HAL API version 1
498 {
499 result = cyhal_uart_init(&cy_trans_uart.hal_obj, config->uart_tx_pin, config->uart_rx_pin, NULL, &uart_config);
500 if(result != CY_RSLT_SUCCESS)
501 return CYBT_ERR_HCI_INIT_FAILED;
502
503 if (config->flow_control)
504 {
505 result = cyhal_uart_set_flow_control(&cy_trans_uart.hal_obj, config->uart_cts_pin, config->uart_rts_pin);
506 }
507 }
508 #endif
509
510 if(result != CY_RSLT_SUCCESS)
511 return (CYBT_ERR_HCI_INIT_FAILED);
512
513 #if ( (CYHAL_UART_DMA_ENABLE_RX == TRUE) || (CYHAL_UART_DMA_ENABLE_TX == TRUE) )
514 cyhal_uart_set_async_mode(&cy_trans_uart.hal_obj, CYHAL_ASYNC_DMA, 3);
515 #endif
516
517 result = cyhal_uart_set_baud(&cy_trans_uart.hal_obj, config->baud_rate, NULL);
518 if(result != CY_RSLT_SUCCESS)
519 return (CYBT_ERR_HCI_INIT_FAILED);
520
521 if(!cybt_debug_uart_setup)
522 {
523 #ifndef DISABLE_TX_TASK
524 cy_rtos_init_semaphore(&cy_trans_uart.tx_complete, 1, 0);
525 cy_rtos_init_semaphore(&cy_trans_uart.tx_ready, 1, 1);
526 #endif
527 cy_rtos_init_semaphore(&cy_trans_uart.rx_complete, 1, 0);
528
529 cy_rtos_init_mutex(&cy_trans_uart.tx_atomic);
530 }
531
532 cyhal_uart_register_callback(&cy_trans_uart.hal_obj, cybt_uart_irq_handler_, NULL);
533
534 cyhal_uart_enable_event(&cy_trans_uart.hal_obj, (cyhal_uart_event_t)enable_irq_event,
535 CYHAL_ISR_PRIORITY_DEFAULT, true);
536
537 cy_trans_uart.inited = true;
538 p_app_rx_cmd_handler = p_data_handler;
539
540 if(!cybt_debug_uart_setup)
541 {
542 cybt_debug_uart_setup = true;
543 }
544 return CYBT_SUCCESS;
545 }
546
cybt_debug_uart_deinit()547 void cybt_debug_uart_deinit()
548 {
549 if(cybt_debug_uart_setup)
550 {
551 cyhal_uart_free(&cy_trans_uart.hal_obj);
552 cy_trans_uart.inited = false;
553 cy_rtos_set_semaphore(&cy_trans_uart.tx_complete, true);
554 }
555 }
556
cybt_debug_uart_send_trace(uint16_t length,uint8_t * p_data)557 cybt_result_t cybt_debug_uart_send_trace(uint16_t length, uint8_t* p_data)
558 {
559 #ifdef DISABLE_TX_TASK
560 return cybt_trans_blocking_write(INVALID_TYPE, HCI_CONTROL_EVENT_WICED_TRACE, length, p_data);
561 #else
562 return cybt_enqueue_tx_data(INVALID_TYPE, HCI_CONTROL_EVENT_WICED_TRACE, length, p_data);
563 #endif
564 }
565
566 BTSTACK_PORTING_SECTION_BEGIN
cybt_debug_uart_send_data(uint16_t opcode,uint16_t data_size,uint8_t * p_data)567 cybt_result_t cybt_debug_uart_send_data (uint16_t opcode, uint16_t data_size, uint8_t *p_data)
568 {
569 #ifdef DISABLE_TX_TASK
570 return cybt_trans_blocking_write(INVALID_TYPE,(uint16_t)opcode, data_size, p_data);
571 #else
572 return cybt_enqueue_tx_data(INVALID_TYPE, (uint16_t)opcode, data_size, p_data);
573 #endif
574 }
575 BTSTACK_PORTING_SECTION_END
576
577 BTSTACK_PORTING_SECTION_BEGIN
cybt_debug_uart_send_hci_trace(uint8_t type,uint16_t data_size,uint8_t * p_data)578 cybt_result_t cybt_debug_uart_send_hci_trace (uint8_t type, uint16_t data_size, uint8_t *p_data)
579 {
580 #ifdef DISABLE_TX_TASK
581 return cybt_trans_blocking_write((uint16_t)type, HCI_CONTROL_EVENT_HCI_TRACE, data_size, p_data);
582 #else
583 return cybt_enqueue_tx_data((uint16_t)type, HCI_CONTROL_EVENT_HCI_TRACE, data_size, p_data);
584 #endif
585 }
586 BTSTACK_PORTING_SECTION_END
587
cybt_send_coredump_hci_trace(uint16_t data_size,uint8_t * p_data)588 cybt_result_t cybt_send_coredump_hci_trace (uint16_t data_size, uint8_t *p_data)
589 {
590 #ifdef DISABLE_TX_TASK
591 return cybt_trans_blocking_write(GENERIC_TYPE, HCI_CONTROL_EVENT_HCI_TRACE, data_size, p_data);
592 #else
593 return cybt_enqueue_tx_data(GENERIC_TYPE, HCI_CONTROL_EVENT_HCI_TRACE, data_size, p_data);
594 #endif
595 }
596
597 #ifdef DISABLE_TX_TASK
598
599 BTSTACK_PORTING_SECTION_BEGIN
cybt_trans_blocking_write(uint8_t type,uint16_t op,uint16_t data_size,uint8_t * p_data)600 cybt_result_t cybt_trans_blocking_write (uint8_t type, uint16_t op, uint16_t data_size, uint8_t *p_data)
601 {
602 cybt_result_t result = CYBT_ERR_GENERIC;
603 cy_rslt_t status = CY_RSLT_SUCCESS;
604 size_t index = 0;
605 uint8_t opcode = (uint8_t)(op&0xff);
606 uint8_t group_code = (uint8_t)((op >> 8)&0xff);
607 uint8_t data[2000];
608 int nChars = 0;
609 char *ptr = NULL;
610
611 if (cy_trans_uart.inited == false)
612 return CYBT_ERR_GENERIC;
613
614 status = cy_rtos_get_mutex(&cy_trans_uart.tx_atomic, CY_RTOS_NEVER_TIMEOUT);
615
616 if(CY_RSLT_SUCCESS != status)
617 {
618 return result;
619 }
620
621 data[index++] = HCI_WICED_PKT;
622
623 if ( (type != 0xFF) || ((group_code == 0x00) && (opcode == 0x03)) )
624 {
625 uint16_t new_size = (data_size+1);
626 data[index++] = 0x03;
627 data[index++] = 0x00;
628 data[index++] = (uint8_t)(new_size&0xff);
629 data[index++] = (uint8_t)((new_size >> 8)&0xff);
630 data[index++] = type;
631 }
632 else
633 {
634 data[index++] = opcode;
635 data[index++] = group_code;
636 data[index++] = (uint8_t)(data_size&0xff);
637 data[index++] = (uint8_t)((data_size >> 8)&0xff);
638 }
639 memcpy(&data[index], p_data, data_size);
640 index += data_size;
641
642 /*! NB TODO
643 * Remove local data var. Print individual bytes. */
644 ptr = (char *)&data[0];
645 for (/* Empty */; nChars < index; ++nChars)
646 {
647 cyhal_uart_putc(&cy_trans_uart.hal_obj, *ptr);
648 ++ptr;
649 }
650
651 cy_rtos_set_mutex(&cy_trans_uart.tx_atomic);
652 return result;
653 }
654 BTSTACK_PORTING_SECTION_END
655 #endif // DISABLE_TX_TASK
656
_write(int fd,const char * ptr,int len)657 int _write(int fd, const char* ptr, int len)
658 {
659 if(cybt_debug_uart_send_trace(len,(uint8_t* )ptr) == CYBT_SUCCESS)
660 {
661 return len;
662 }
663 return 0;
664 }
665
666 #endif // ENABLE_DEBUG_UART
667