1 /**
2  * Copyright (c) 2015, Realsil Semiconductor Corporation. All rights reserved.
3  *
4  */
5 
6 #include <stdio.h>
7 #include <stdarg.h>
8 #include <string.h>
9 #include <stdint.h>
10 
11 #include "os_msg.h"
12 #include "os_task.h"
13 
14 #include "trace_app.h"
15 #include "cycle_queue.h"
16 #include "bt_board.h"
17 #include "trace_uart.h"
18 
19 #define TRACE_QUEUE_LENGTH_EVENT      0x80
20 
21 #define TRACE_EVENT_TX                0
22 #define TRACE_EVENT_TX_COMPLETED      1
23 
24 typedef struct _TTraceTaskBuffer
25 {
26     uint8_t     *Pointer;
27     uint16_t Length;
28 } TTraceTaskBuffer;
29 
30 typedef struct
31 {
32     void               *handle;               /* task handle */
33     void               *QueueHandleEvent;     /* task queue */
34     TTraceTaskBuffer    Buffer;               /* actual buffer */
35 } T_TRACE_TASK_INFO;
36 
37 static T_TRACE_TASK_INFO trace;
38 
39 
traceuart_tx_cb(void)40 bool traceuart_tx_cb(void)
41 {
42     uint8_t Event = TRACE_EVENT_TX_COMPLETED;
43     os_msg_send(trace.QueueHandleEvent, &Event, 0);
44     return true;
45 }
46 
47 //=========================interal======================
traceStartTransmit(void)48 static void traceStartTransmit(void)
49 {
50     uint16_t queueSize = CycQueueSize();
51 
52     if (trace.Buffer.Pointer == (uint8_t *)0 && (queueSize > 0))
53     {
54         trace.Buffer.Pointer = (uint8_t *)(cyc_buffer + pRead);
55 
56         if (pRead + queueSize >= MAX_BUFFER_SIZE)
57         {
58             trace.Buffer.Length = MAX_BUFFER_SIZE - pRead;
59         }
60         else
61         {
62             trace.Buffer.Length = queueSize;
63         }
64         trace_uart_tx(trace.Buffer.Pointer, trace.Buffer.Length,traceuart_tx_cb);
65     }
66 }
67 
trace_task(void * pParameters)68 static void trace_task(void *pParameters)
69 {
70     (void)pParameters;
71     while (1)
72     {
73         uint8_t Event;
74 
75         if (os_msg_recv(trace.QueueHandleEvent, &Event, 0xFFFFFFFF) == true)
76         {
77             switch (Event)
78             {
79             case TRACE_EVENT_TX:            /* new trace output */
80                 traceStartTransmit();
81                 break;
82 
83             case TRACE_EVENT_TX_COMPLETED:  /* transmit completed */
84                 if (trace.Buffer.Pointer != (uint8_t *)0)
85                 {
86                     trace.Buffer.Pointer = (uint8_t *)0;
87                     UpdateQueueRead(trace.Buffer.Length);
88                     trace.Buffer.Length = 0;
89                 }
90                 traceStartTransmit();
91                 break;
92 
93             default:
94                 break;
95             }
96         }
97     }
98 }
99 
100 //========================================
bt_trace_init(void)101 bool bt_trace_init(void)
102 {
103     trace_uart_init();
104 
105     if((trace.handle != NULL)&&(trace.QueueHandleEvent != NULL))
106     {
107         platform_debug("reopen bt trace, do nothing\r\n");
108         return false;
109     }
110 
111     os_msg_queue_create(&trace.QueueHandleEvent, TRACE_QUEUE_LENGTH_EVENT, sizeof(uint8_t));
112     os_task_create(&trace.handle, "trace_task", trace_task, NULL, 0x200, TRACE_TASK_PRIO);   /*need up priority */
113 
114     return true;
115 }
116 
bt_trace_uninit(void)117 bool bt_trace_uninit(void)
118 {
119     FreeCycQueue();
120     trace_uart_deinit();
121 	if(trace.handle != NULL)
122 		os_task_delete(trace.handle);
123 	if(trace.QueueHandleEvent != NULL)
124 		os_msg_queue_delete(trace.QueueHandleEvent);
125 
126 	trace.handle = NULL;
127 	trace.QueueHandleEvent = NULL;
128     return true;
129 }
130 
trace_print(void * pData,uint16_t Length)131 bool trace_print(void *pData, uint16_t Length)
132 {
133     //just debug
134      //platform_debug("trace_print:buffer is ok, need %d, left %d\r\npread: %d, pWrite :%d", Length,CycQueueRemainSize(), pRead, pWrite);
135     if(trace.handle == NULL)
136     {
137         platform_debug("trace task is deleted, not work\r\n");
138         return false;
139     }
140 
141     if (CycQueueWrite(pData, Length))
142     {
143         uint8_t Event = TRACE_EVENT_TX;
144         os_msg_send(trace.QueueHandleEvent, &Event, 0);
145         return true;
146     }
147     else
148     {
149        // platform_debug("\r\ntrace_print:buffer is full, need %d, left %d\r\n", Length,CycQueueRemainSize());
150 
151         return false;
152     }
153 }
154