1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <data_uart.h>
4 #include <os_msg.h>
5 #include <trace_app.h>
6 #include <app_msg.h>
7 #include "ameba_soc.h"
8 
9 #ifdef CONFIG_BT_USER_COMMAND
10 #define USE_DEDICATED_BT_DATA_UART    CONFIG_BT_USER_COMMAND
11 #else
12 #define USE_DEDICATED_BT_DATA_UART    0
13 #endif
14 
15 static void *h_event_q;
16 static void *h_io_q;
17 UART_TypeDef *data_uart_def;
18 
19 int data_uart_send_char(int ch);
20 
data_uart_msg_init(void * event_queue_handle,void * io_queue_handle)21 void data_uart_msg_init(void *event_queue_handle, void *io_queue_handle)
22 {
23     h_event_q = event_queue_handle;
24     h_io_q = io_queue_handle;
25 }
26 
data_uart_msg_send(uint8_t rx_char)27 void data_uart_msg_send(uint8_t rx_char)
28 {
29     T_IO_MSG io_driver_msg_send;
30     uint8_t event  = EVENT_IO_TO_APP;
31     io_driver_msg_send.type = IO_MSG_TYPE_UART;
32     io_driver_msg_send.subtype = rx_char;
33 
34     if (os_msg_send(h_io_q, &io_driver_msg_send, 0) == false)
35     {
36         APP_PRINT_ERROR0("data_uart_msg_send: send data failed");
37     }
38     else if (os_msg_send(h_event_q, &event, 0) == false)
39     {
40         APP_PRINT_ERROR0("data_uart_msg_send: send event failed");
41     }
42 }
43 
data_uart_vsprintf(char * buf,const char * fmt,const int * dp)44 int data_uart_vsprintf(char *buf, const char *fmt, const int *dp)
45 {
46     char *p, *s;
47 
48     s = buf;
49     for (; *fmt != '\0'; ++fmt)
50     {
51         if (*fmt != '%')
52         {
53             buf ? *s++ = *fmt : data_uart_send_char(*fmt);
54             continue;
55         }
56         if (*++fmt == 's')
57         {
58             for (p = (char *)*dp++; *p != '\0'; p++)
59             {
60                 buf ? *s++ = *p : data_uart_send_char(*p);
61             }
62         }
63         else    /* Length of item is bounded */
64         {
65             char tmp[20], *q = tmp;
66             int shift = 28;
67 
68             if ((*fmt  >= '0') && (*fmt  <= '9'))
69             {
70                 int width;
71                 unsigned char fch = *fmt;
72                 for (width = 0; (fch >= '0') && (fch <= '9'); fch = *++fmt)
73                 {
74                     width = width * 10 + fch - '0';
75                 }
76                 shift = (width - 1) * 4;
77             }
78             /*
79              * Before each format q points to tmp buffer
80              * After each format q points past end of item
81              */
82 
83             if ((*fmt == 'x') || (*fmt == 'X') || (*fmt == 'p') || (*fmt == 'P'))
84             {
85                 /* With x86 gcc, sizeof(long) == sizeof(int) */
86                 const long *lp = (const long *)dp;
87                 long h = *lp++;
88                 int ncase = (*fmt & 0x20);
89                 int alt = 0;
90 
91                 dp = (const int *)lp;
92                 if ((*fmt == 'p') || (*fmt == 'P'))
93                 {
94                     alt = 1;
95                 }
96                 if (alt)
97                 {
98                     *q++ = '0';
99                     *q++ = 'X' | ncase;
100                 }
101                 for (; shift >= 0; shift -= 4)
102                 {
103                     * q++ = "0123456789ABCDEF"[(h >> shift) & 0xF] | ncase;
104                 }
105             }
106             else if (*fmt == 'd')
107             {
108                 int i = *dp++;
109                 char *r;
110                 if (i < 0)
111                 {
112                     *q++ = '-';
113                     i = -i;
114                 }
115                 p = q;      /* save beginning of digits */
116                 do
117                 {
118                     *q++ = '0' + (i % 10);
119                     i /= 10;
120                 }
121                 while (i);
122                 /* reverse digits, stop in middle */
123                 r = q;      /* don't alter q */
124                 while (--r > p)
125                 {
126                     i = *r;
127                     *r = *p;
128                     *p++ = i;
129                 }
130             }
131             else if (*fmt == 'c')
132             {
133                 *q++ = *dp++;
134             }
135             else
136             {
137                 *q++ = *fmt;
138             }
139             /* now output the saved string */
140             for (p = tmp; p < q; ++p)
141             {
142                 buf ? *s++ = *p : data_uart_send_char(*p);
143             }
144         }
145     }
146     if (buf)
147     {
148         *s = '\0';
149     }
150     return (s - buf);
151 }
152 
data_uart_print(char * fmt,...)153 void data_uart_print(char *fmt, ...)
154 {
155     (void)data_uart_vsprintf(0, fmt, ((const int *)&fmt) + 1);
156 }
157 
data_uart_send_char(int ch)158 int data_uart_send_char(int ch)
159 {
160 #if (USE_DEDICATED_BT_DATA_UART == 0)
161 		LOGUART_PutChar((uint8_t)ch);
162 #else
163     UART_CharPut(data_uart_def, (u8)ch);
164     UART_WaitBusy(data_uart_def, 10);
165 #endif
166     return ch;
167 }
168 
169 /****************************************************************************/
170 /* UART interrupt                                                           */
171 /****************************************************************************/
data_uart_irq(void * data)172 u32 data_uart_irq(void *data)
173 {
174     (void) data;
175     volatile u8 reg_iir;
176     u8 int_id;
177     u32 reg_val;
178     uint8_t rx_char;
179 
180     reg_iir = UART_IntStatus(data_uart_def);
181     if ((reg_iir & RUART_IIR_INT_PEND) != 0)
182     {
183         /* No pending IRQ */
184         return 0;
185     }
186 
187     int_id = (reg_iir & RUART_IIR_INT_ID) >> 1;
188 
189     switch (int_id)
190     {
191     case RUART_RECEIVER_DATA_AVAILABLE:
192     case RUART_TIME_OUT_INDICATION:
193         {
194             if (UART_Readable(data_uart_def))
195             {
196                 UART_CharGet(data_uart_def, &rx_char);
197                 data_uart_msg_send(rx_char);
198             }
199         }
200         break;
201 
202     case RUART_RECEIVE_LINE_STATUS:
203         reg_val = (UART_LineStatusGet(data_uart_def));
204         APP_PRINT_INFO1("data_uart_irq: LSR %08x interrupt", reg_val);
205         break;
206 
207     default:
208         APP_PRINT_ERROR1("data_uart_irq: Unknown interrupt type %u", int_id);
209         break;
210     }
211 
212     return 0;
213 }
214 
215 #define DATAUART_IRQ_PRIO      11
216 /**
217   * UART Parameter
218   * BaudRate: 115200
219   * Word Length: 8 bit
220   * Stop Bit: 1 bit
221   * Parity: None
222   * RX FIFO: 1 byte
223   */
data_uart_init(void * event_queue_handle,void * io_queue_handle)224 void data_uart_init(void *event_queue_handle, void *io_queue_handle)
225 {
226     data_uart_msg_init(event_queue_handle, io_queue_handle);
227 #if (USE_DEDICATED_BT_DATA_UART == 1)
228 //PIN TX:A_18 RX:PA 19
229     IRQn_Type irqn = UART0_IRQ;
230     UART_InitTypeDef    UART_InitStruct;
231     Pinmux_Config(_PA_18, PINMUX_FUNCTION_UART);
232     Pinmux_Config(_PA_19, PINMUX_FUNCTION_UART);
233 
234     PAD_PullCtrl(_PA_18, GPIO_PuPd_UP);
235     PAD_PullCtrl(_PA_19, GPIO_PuPd_UP);
236     data_uart_def = UART0_DEV;
237 
238     //UART_PinMuxInit(0, S0);
239     UART_StructInit(&UART_InitStruct);
240     UART_InitStruct.WordLen = RUART_WLS_8BITS;
241     UART_InitStruct.StopBit = RUART_STOP_BIT_1;
242     UART_InitStruct.Parity = RUART_PARITY_DISABLE;
243     UART_InitStruct.ParityType = RUART_EVEN_PARITY;
244     UART_InitStruct.StickParity = RUART_STICK_PARITY_DISABLE;
245     UART_InitStruct.RxFifoTrigLevel = UART_RX_FIFOTRIG_LEVEL_1BYTES;
246     UART_InitStruct.FlowControl = FALSE;
247     UART_Init(data_uart_def, &UART_InitStruct);
248     UART_SetBaud(data_uart_def, 115200);
249 
250     InterruptDis(irqn);
251     InterruptUnRegister(irqn);
252     InterruptRegister((IRQ_FUN)data_uart_irq, irqn, NULL, DATAUART_IRQ_PRIO);
253     InterruptEn(irqn, DATAUART_IRQ_PRIO);
254     UART_INTConfig(data_uart_def, RUART_IER_ERBI | RUART_IER_ETOI | RUART_IER_ELSI, ENABLE);
255 
256     UART_RxCmd(data_uart_def, ENABLE);
257 #endif
258 }
259 
260