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