• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <stdio.h>
2 #include <string.h>
3 #include "SEGGER_RTT.h"
4 #include "dbg_printf.h"
5 
6 #define LOG_UART_GRP                    UART0
7 #define LOG_UART_PORT                   GPIO0
8 #define LOG_UART_TX_PIN                 GPIO_PIN_10
9 #define LOG_UART_RX_PIN                 GPIO_PIN_11
10 #define LOG_UART_TX_PINMUX              GPIO_MUX_2
11 #define LOG_UART_RX_PINMUX              GPIO_MUX_2
12 
13 
14 typedef struct {
15     char     send_buf[DBG_RING_BUF_SIZE];
16     uint32_t head;
17     uint32_t tail;
18     uint32_t valid;
19 } ring_buf_t;
20 
21 static ring_buf_t dbg_ring_buf;
22 static dbg_printf_mode_t dbg_printf_mode = DBG_PRINTF_NONE;
23 volatile int32_t ITM_RxBuffer = 0x5AA55AA5U;
24 
SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex,const char * sName,uint8_t * pBuffer,unsigned BufferSize,unsigned Flags)25 __WEAK int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, uint8_t* pBuffer, unsigned BufferSize,
26                                      unsigned Flags)
27 {
28     return 0;
29 }
30 
SEGGER_RTT_Write(unsigned BufferIndex,const uint8_t * pBuffer,unsigned NumBytes)31 __WEAK unsigned SEGGER_RTT_Write(unsigned BufferIndex, const uint8_t* pBuffer, unsigned NumBytes)
32 {
33     return 0;
34 }
35 
SEGGER_RTT_WaitKey(void)36 __WEAK int SEGGER_RTT_WaitKey(void)
37 {
38     return 0;
39 }
40 
push_char(ring_buf_t * p_ring_buf,uint8_t ch)41 static uint8_t push_char(ring_buf_t *p_ring_buf, uint8_t ch)
42 {
43     uint8_t ret = 0;
44 
45     GLOBAL_EXCEPTION_DISABLE();
46     if (p_ring_buf->valid < DBG_RING_BUF_SIZE) {
47         p_ring_buf->send_buf[p_ring_buf->tail++] = ch;
48         if (p_ring_buf->tail == DBG_RING_BUF_SIZE)
49             p_ring_buf->tail = 0;
50         p_ring_buf->valid++;
51         ret = 1;
52     } else {
53         ret = 0;
54     }
55     GLOBAL_EXCEPTION_ENABLE();
56 
57     return ret;
58 }
59 
pop_char(ring_buf_t * p_ring_buf)60 static uint8_t pop_char(ring_buf_t *p_ring_buf)
61 {
62     uint8_t ret = 0;
63 
64     GLOBAL_EXCEPTION_DISABLE();
65     if (p_ring_buf->valid) {
66         p_ring_buf->valid--;
67         ret =  p_ring_buf->send_buf[p_ring_buf->head++];
68         if (p_ring_buf->head == DBG_RING_BUF_SIZE)
69             p_ring_buf->head = 0;
70     } else {
71         ret = 0;
72     }
73     GLOBAL_EXCEPTION_ENABLE();
74 
75     return ret;
76 }
77 
dbg_uart_init(uart_regs_t * UARTx,dbg_printf_mode_t mode)78 static void dbg_uart_init(uart_regs_t *UARTx, dbg_printf_mode_t mode)
79 {
80     uint32_t baud;
81     uint32_t uart_pclk = SystemCoreClock;
82     gpio_init_t gpio_config = GPIO_DEFAULT_CONFIG;
83 
84     /* Initialize ring buffer */
85     memset_s(&dbg_ring_buf, sizeof (dbg_ring_buf), 0, sizeof(dbg_ring_buf));
86 
87     /* Enable serial module clock */
88     ll_cgc_disable_force_off_serial_hclk();
89     ll_cgc_disable_wfi_off_serial_hclk();
90 
91     if (UARTx == UART0) {
92         /* Enable UART0 clock */
93         ll_cgc_disable_force_off_uart0_hclk();
94     } else if (UARTx == UART1) {
95         /* Enable UART1 clock */
96         ll_cgc_disable_force_off_uart1_hclk();
97     }
98 
99     gpio_config.mode = GPIO_MODE_MUX;
100     gpio_config.pin  = LOG_UART_TX_PIN;
101     gpio_config.mux  = LOG_UART_TX_PINMUX;
102     hal_gpio_init(LOG_UART_PORT, &gpio_config);
103 
104     gpio_config.pin  = LOG_UART_RX_PIN;
105     gpio_config.mux  = LOG_UART_RX_PINMUX;
106     hal_gpio_init(LOG_UART_PORT, &gpio_config);
107 
108     /* Set baudrate */
109     baud = DBG_UART_BAUDRATE;
110     ll_uart_set_baud_rate(UARTx, uart_pclk, baud);
111 
112     /**
113     Set data bit to 8.
114     Set stop bit to 1.
115     Set parity to none.
116     Set fifo to enable.
117     */
118     ll_uart_config_character(UARTx, LL_UART_DATABITS_8B, LL_UART_PARITY_NONE, LL_UART_STOPBITS_1);
119     /* Set fifo enable */
120     ll_uart_enable_fifo(UARTx);
121 
122     if ((DBG_PRINTF_INT_UART0 == mode) || (DBG_PRINTF_INT_UART1 == mode)) {
123         /* Set tx fifo threshold */
124         ll_uart_set_tx_fifo_threshold(UARTx, LL_UART_TX_FIFO_TH_EMPTY);
125 
126         /* Enable NVIC uart interrupt */
127         IRQn_Type uart_irq_num = ((UARTx == UART0) ? UART0_IRQn : UART1_IRQn);
128         NVIC_SetPriority(uart_irq_num, 0xF0);
129         NVIC_ClearPendingIRQ(uart_irq_num);
130         NVIC_EnableIRQ(uart_irq_num);
131     }
132     return;
133 }
134 
dbg_uart_send_char(uart_regs_t * UARTx,uint8_t ch)135 static void dbg_uart_send_char(uart_regs_t *UARTx, uint8_t ch)
136 {
137     if ((DBG_PRINTF_UART0 == dbg_printf_mode) || (DBG_PRINTF_UART1 == dbg_printf_mode)) {
138         /* Wait untill TX FIFO is not full */
139         while (!ll_uart_is_active_flag_tfnf(UARTx));
140         ll_uart_transmit_data8(UARTx, ch);
141     } else if ((DBG_PRINTF_INT_UART0 == dbg_printf_mode) || (DBG_PRINTF_INT_UART1 == dbg_printf_mode)) {
142         /* Fill ring buffer to use interrupt send */
143         push_char(&dbg_ring_buf, ch);
144         /* Enable TXE interrupt */
145         ll_uart_enable_it(UARTx, LL_UART_IER_THRE);
146     }
147     return;
148 }
149 
dbg_uart_get_char(uart_regs_t * UARTx)150 static uint8_t dbg_uart_get_char(uart_regs_t *UARTx)
151 {
152     uint8_t ch;
153 
154     while (!ll_uart_is_active_flag_rfne(UARTx));
155     /* UART receive byte */
156     ch = ll_uart_receive_data8(UARTx);
157     return ch;
158 }
159 
dbg_send_char(int ch)160 static int dbg_send_char(int ch)
161 {
162     switch (dbg_printf_mode) {
163         case DBG_PRINTF_UART0:
164         case DBG_PRINTF_INT_UART0:
165             dbg_uart_send_char(UART0, (uint8_t)ch);
166             break;
167         case DBG_PRINTF_UART1:
168         case DBG_PRINTF_INT_UART1:
169             dbg_uart_send_char(UART1, (uint8_t)ch);
170             break;
171         case DBG_PRINTF_ITM:
172             ITM_SendChar(ch);
173             break;
174         case DBG_PRINTF_RTT:
175             SEGGER_RTT_Write(0, &ch, 1);
176             break;
177         default:
178             break;
179     }
180     return ch;
181 }
182 
dbg_get_char(void)183 static int dbg_get_char(void)
184 {
185     int32_t ch = -1;
186 
187     switch (dbg_printf_mode) {
188         case DBG_PRINTF_UART0:
189         case DBG_PRINTF_INT_UART0:
190             ch = dbg_uart_get_char(UART0);
191             break;
192         case DBG_PRINTF_UART1:
193         case DBG_PRINTF_INT_UART1:
194             ch = dbg_uart_get_char(UART1);
195             break;
196         case DBG_PRINTF_ITM:
197             while (ITM_CheckChar() == 0) {
198             }
199             ch = ITM_ReceiveChar();
200             break;
201         case DBG_PRINTF_RTT:
202             ch = SEGGER_RTT_WaitKey();
203             break;
204         default:
205             break;
206     }
207     return ch;
208 }
209 
dbg_printf_set_mode(dbg_printf_mode_t mode)210 void dbg_printf_set_mode(dbg_printf_mode_t mode)
211 {
212     switch (mode) {
213         case DBG_PRINTF_UART0:
214         case DBG_PRINTF_INT_UART0:
215             dbg_uart_init(UART0, mode);
216             break;
217         case DBG_PRINTF_UART1:
218         case DBG_PRINTF_INT_UART1:
219             dbg_uart_init(UART1, mode);
220             break;
221         case DBG_PRINTF_ITM:
222             /* Set MUX2 of GPIO_PIN_2 to enable SWV. */
223             ll_gpio_set_mux_pin_0_7(GPIO0, LL_GPIO_PIN_2, LL_GPIO_MUX_2);
224             break;
225         case DBG_PRINTF_RTT:
226             SEGGER_RTT_ConfigUpBuffer(0, NULL, NULL, 0, SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL);
227             break;
228         default:
229             break;
230     }
231 
232     dbg_printf_mode = mode;
233     return;
234 }
235 
dbg_printf_uart_callback(uart_regs_t * UARTx)236 uint8_t dbg_printf_uart_callback(uart_regs_t *UARTx)
237 {
238     uint32_t isrflag = ll_uart_get_it_flag(UARTx);
239     if (LL_UART_IIR_THRE == isrflag) {
240         if (dbg_ring_buf.valid == 0) {
241             /* Disable TXE interrupt */
242             ll_uart_disable_it(UARTx, LL_UART_IER_THRE);
243         } else {
244             uint8_t curxfercnt = UART_TXFIFO_SIZE - ll_uart_get_tx_fifo_level(UARTx);
245             while (curxfercnt && dbg_ring_buf.valid) {
246                 ll_uart_transmit_data8(UARTx, pop_char(&dbg_ring_buf));
247                 curxfercnt--;
248             }
249         }
250         return 1;
251     } else {
252         return 0;
253     }
254 }
255 
dbg_printf_uart_flush(void)256 uint32_t dbg_printf_uart_flush(void)
257 {
258     uint32_t count = 0;
259     if ((DBG_PRINTF_INT_UART0 == dbg_printf_mode) || (DBG_PRINTF_INT_UART1 == dbg_printf_mode)) {
260         uart_regs_t *UARTx = ((DBG_PRINTF_INT_UART0 == dbg_printf_mode)? UART0: UART1);
261         IRQn_Type uart_irq_num = ((DBG_PRINTF_INT_UART0 == dbg_printf_mode) ? UART0_IRQn : UART1_IRQn);
262 
263         NVIC_DisableIRQ(uart_irq_num);
264         NVIC_ClearPendingIRQ(uart_irq_num);
265         count = dbg_ring_buf.valid;
266         while (dbg_ring_buf.valid) {
267             /* Wait untill TX FIFO is not full */
268             while (!ll_uart_is_active_flag_tfnf(UARTx));
269             ll_uart_transmit_data8(UARTx, pop_char(&dbg_ring_buf));
270         }
271         /* Wait untill TX FIFO is empty. */
272         while (!ll_uart_is_active_flag_tfe(UARTx));
273         NVIC_EnableIRQ(uart_irq_num);
274     } else if ((DBG_PRINTF_UART0 == dbg_printf_mode) || (DBG_PRINTF_UART1 == dbg_printf_mode)) {
275         uart_regs_t *UARTx = ((DBG_PRINTF_UART0 == dbg_printf_mode)? UART0: UART1);
276         /* Wait untill TX FIFO is empty. */
277         while (!ll_uart_is_active_flag_tfe(UARTx));
278     }
279 
280     return count;
281 }
282 
283 #if defined(__CC_ARM)
284 
285 struct __FILE {
286     int handle;
287 };
288 
fputc(int ch,FILE * file)289 int fputc(int ch, FILE * file)
290 {
291     return (dbg_send_char(ch));
292 }
293 
fgetc(FILE * file)294 int fgetc(FILE * file)
295 {
296     return dbg_get_char();
297 }
298 
_sys_exit(int return_code)299 void _sys_exit(int return_code)
300 {
301     while (1) {
302         ;
303     }
304 }
305 
306 #elif defined(__GNUC__)
307 
_write(int file,const char * buf,int len)308 int _write(int file, const char *buf, int len)
309 {
310     int tx_len = 0;
311     char *temp_buf = buf;
312 
313     while (tx_len < len) {
314         dbg_send_char(*temp_buf);
315         temp_buf++;
316         tx_len++;
317     }
318     return tx_len;
319 }
320 
_read(int file,char * buf,int len)321 int _read(int file, char *buf, int len)
322 {
323     int rx_len = 0;
324     char *temp_buf = buf;
325 
326     while (rx_len < len) {
327         *temp_buf = dbg_get_char();
328         temp_buf++;
329         rx_len++;
330     }
331     return rx_len;
332 }
333 
334 
335 #elif defined(__ICCARM__)
336 
_write(int handle,const unsigned char * buf,size_t size)337 size_t _write(int handle, const unsigned char * buf, size_t size)
338 {
339     size_t len = 0;
340 
341     while (len < size) {
342         dbg_send_char(*buf);
343         buf++;
344         len++;
345     }
346     return len;
347 }
348 
_read(int handle,unsigned char * buf,size_t size)349 size_t _read(int handle, unsigned char * buf, size_t size)
350 {
351     int rx_len = 0;
352 
353     while (rx_len < size) {
354         *buf = dbg_get_char();
355         buf++;
356         rx_len++;
357     }
358     return rx_len;
359 }
360 
361 #endif /* defined(__CC_ARM) */
362