| Nano102_112 Series BSP V3.03.002 The Board Support Package for Nano102_112 Series

retarget.c
Go to the documentation of this file.
1 /**************************************************************************/
12 #include <stdio.h>
13 #include "Nano1X2Series.h"
14
15 #if defined ( __CC_ARM )
16 #if (__ARMCC_VERSION < 400000)
17 #else
18 /* Insist on keeping widthprec, to avoid X propagation by benign code in C-lib */
19 #pragma import _printf_widthprec
20 #endif
21 #endif
22
23 #ifndef DEBUG_PORT
24 #define DEBUG_PORT UART0
25 #endif
26
27 /* Un-comment this line to disable all printf and getchar. getchar() will always return 0x00*/
28 //#define DISABLE_UART
29
30 #if defined(DEBUG_ENABLE_SEMIHOST)
31 #ifndef DISABLE_UART
32 #define DISABLE_UART
33 #endif
34 #endif
35
36 /*---------------------------------------------------------------------------------------------------------*/
37 /* Global variables */
38 /*---------------------------------------------------------------------------------------------------------*/
39
40 #if !(defined(__ICCARM__) && (__VER__ >= 6010000))
41 struct __FILE
42 {
43 int handle; /* Add whatever you need here */
44 };
45 #endif
46 FILE __stdout;
47 FILE __stdin;
48
49 enum { r0, r1, r2, r3, r12, lr, pc, psr};
50
51 void stackDump(uint32_t stack[])
52 {
53 printf("r0 = 0x%x\n", stack[r0]);
54 printf("r1 = 0x%x\n", stack[r1]);
55 printf("r2 = 0x%x\n", stack[r2]);
56 printf("r3 = 0x%x\n", stack[r3]);
57 printf("r12 = 0x%x\n", stack[r12]);
58 printf("lr = 0x%x\n", stack[lr]);
59 printf("pc = 0x%x\n", stack[pc]);
60 printf("psr = 0x%x\n", stack[psr]);
61 }
62
63 void Hard_Fault_Handler(uint32_t stack[])
64 {
65 printf("In Hard Fault Handler\n");
66
67 stackDump(stack);
68
69 //Chip Reset
70 //SYS_UnlockReg();
71 //SYS->IPRST_CTL1 |= SYS_IPRST_CTL1_CHIP_RST_Msk;
72
73 while(1);
74 }
75
76
77 #if defined(DEBUG_ENABLE_SEMIHOST)
78 /* The static buffer is used to speed up the semihost */
79 static char g_buf[16];
80 static char g_buf_len = 0;
81
82 /* Make sure won't goes here only because --gnu is defined , so
83 add !__CC_ARM and !__ICCARM__ checking */
84 # if defined ( __GNUC__ ) && !(__CC_ARM) && !(__ICCARM__)
85
86 # elif defined(__ICCARM__)
87
88
99 void HardFault_Handler(void)
100 {
101 asm("MOV R0, lr \n"
102 "LSLS R0, #29 \n" //; Check bit 2
103 "BMI SP_is_PSP \n" //; previous stack is PSP
104 "MRS R0, MSP \n" //; previous stack is MSP, read MSP
105 "B SP_Read_Ready \n"
106 "SP_is_PSP: \n"
107 "MRS R0, PSP \n" //; Read PSP
108 "SP_Read_Ready: \n"
109 "LDR R1, [R0, #24] \n" //; Get previous PC
110 "LDRH R3, [R1] \n" //; Get instruction
111 "LDR R2, [pc, #8] \n" //; The sepcial BKPT instruction
112 "CMP R3, R2 \n" //; Test if the instruction at previous PC is BKPT
113 "BNE HardFault_Handler_Ret\n" //; Not BKPT
114 "ADDS R1, #4 \n" //; Skip BKPT and next line
115 "STR R1, [R0, #24] \n" //; Save previous PC
116 "BX lr \n" //; Return
117 "DCD 0xBEAB \n" //; BKPT instruction code
118 "HardFault_Handler_Ret:\n"
119 "MOVS r0, #4 \n"
120 "MOV r1, LR \n"
121 "TST r0, r1 \n"
122 "BEQ Stack_Use_MSP \n"
123 "MRS R0, PSP \n" //; stack use PSP
124 "B Get_LR_and_Branch \n"
125 "Stack_Use_MSP: \n"
126 "MRS R0, MSP \n" //; stack use MSP
127 "Get_LR_and_Branch: \n"
128 "MOV R1, LR \n" //; LR current value
129 "B Hard_Fault_Handler \n"
130 );
131
132 while(1);
133 }
134
145 int32_t SH_DoCommand(int32_t n32In_R0, int32_t n32In_R1, int32_t *pn32Out_R0)
146 {
147 asm("BKPT 0xAB \n" //; This instruction will cause ICE trap or system HardFault
148 "B SH_ICE \n"
149 "SH_HardFault: \n" //; Captured by HardFault
150 "MOVS R0, #0 \n" //; Set return value to 0
151 "BX lr \n" //; Return
152 "SH_ICE: \n" //; Captured by ICE
153 "CMP R2, #0 \n"
154 "BEQ SH_End \n"
155 "STR R0, [R2]\n" //; Save the return value to *pn32Out_R0
156 "SH_End: \n");
157
158 return 1; //; Return 1 when it is trap by ICE
159
160 }
161
162
163 # else
164
175 __asm int32_t HardFault_Handler(void)
176 {
177
178 MOV R0, LR
179 LSLS R0, #29 //; Check bit 2
180 BMI SP_is_PSP //; previous stack is PSP
181 MRS R0, MSP //; previous stack is MSP, read MSP
182 B SP_Read_Ready
183 SP_is_PSP
184 MRS R0, PSP //; Read PSP
185
186 SP_Read_Ready
187 LDR R1, [R0, #24] //; Get previous PC
188 LDRH R3, [R1] //; Get instruction
189 LDR R2, =0xBEAB //; The sepcial BKPT instruction
190 CMP R3, R2 //; Test if the instruction at previous PC is BKPT
191 BNE HardFault_Handler_Ret //; Not BKPT
192
193 ADDS R1, #4 //; Skip BKPT and next line
194 STR R1, [R0, #24] //; Save previous PC
195
196 BX LR //; Return
197 HardFault_Handler_Ret
198
199 /* TODO: Implement your own hard fault handler here. */
200 MOVS r0, #4
201 MOV r1, LR
202 TST r0, r1
203 BEQ Stack_Use_MSP
204 MRS R0, PSP ; stack use PSP
205 B Get_LR_and_Branch
206 Stack_Use_MSP
207 MRS R0, MSP ; stack use MSP
208 Get_LR_and_Branch
209 MOV R1, LR ; LR current value
210 LDR R2,=__cpp(Hard_Fault_Handler)
211 BX R2
212
213 B .
214
215 ALIGN
216 }
217
228 __asm int32_t SH_DoCommand(int32_t n32In_R0, int32_t n32In_R1, int32_t *pn32Out_R0)
229 {
230 BKPT 0xAB //; Wait ICE or HardFault
231 //; ICE will step over BKPT directly
232 //; HardFault will step BKPT and the next line
233 B SH_ICE
234
235 SH_HardFault //; Captured by HardFault
236 MOVS R0, #0 //; Set return value to 0
237 BX lr //; Return
238
239 SH_ICE //; Captured by ICE
240 //; Save return value
241 CMP R2, #0
242 BEQ SH_End
243 STR R0, [R2] //; Save the return value to *pn32Out_R0
244
245 SH_End
246 MOVS R0, #1 //; Set return value to 1
247 BX lr //; Return
248 }
249 #endif
250
251 #else
252
253 /* Make sure won't goes here only because --gnu is defined , so
254 add !__CC_ARM and !__ICCARM__ checking */
255 # if defined ( __GNUC__ ) && !(__CC_ARM) && !(__ICCARM__)
256
267 void HardFault_Handler(void)
268 {
269 asm("MOVS r0, #4 \n"
270 "MOV r1, LR \n"
271 "TST r0, r1 \n" /*; check LR bit 2 */
272 "BEQ 1f \n" /*; stack use MSP */
273 "MRS R0, PSP \n" /*; stack use PSP, read PSP */
274 "MOV R1, LR \n" /*; LR current value */
275 "B Hard_Fault_Handler \n"
276 "1: \n"
277 "MRS R0, MSP \n" /*; LR current value */
278 "B Hard_Fault_Handler \n"
279 ::[Hard_Fault_Handler] "r" (Hard_Fault_Handler) // input
280 );
281 while(1);
282 }
283
284 # elif defined(__ICCARM__)
285
296 void HardFault_Handler(void)
297 {
298 asm("MOVS r0, #4 \n"
299 "MOV r1, LR \n"
300 "TST r0, r1 \n"
301 "BEQ Stack_Use_MSP \n"
302 "MRS R0, PSP \n" //; stack use PSP
303 "B Get_LR_and_Branch \n"
304 "Stack_Use_MSP: \n"
305 "MRS R0, MSP \n" //; stack use MSP
306 "Get_LR_and_Branch: \n"
307 "MOV R1, LR \n" //; LR current value
308 "B Hard_Fault_Handler \n"
309 );
310
311 while(1);
312 }
313
314 # else
315
326 __asm int32_t HardFault_Handler(void)
327 {
328 MOVS r0, #4
329 MOV r1, LR
330 TST r0, r1
331 BEQ Stack_Use_MSP
332 MRS R0, PSP ;stack use PSP
333 B Get_LR_and_Branch
334 Stack_Use_MSP
335 MRS R0, MSP ;stack use MSP
336 Get_LR_and_Branch
337 MOV R1, LR ;LR current value
338 LDR R2,=__cpp(Hard_Fault_Handler)
339 BX R2
340 }
341
342 #endif
343
344 #endif
345
346
353 void SendChar_ToUART(int ch)
354 {
355 #ifndef DISABLE_UART
356 while(DEBUG_PORT->FSR & UART_FSR_TX_FULL_F_Msk);
357 DEBUG_PORT->THR = ch;
358 if(ch == '\n')
359 {
360 while(DEBUG_PORT->FSR & UART_FSR_TX_FULL_F_Msk);
361 DEBUG_PORT->THR = '\r';
362 }
363 #endif
364 }
365
366
373 void SendChar(int ch)
374 {
375 #if defined(DEBUG_ENABLE_SEMIHOST)
376 g_buf[g_buf_len++] = ch;
377 g_buf[g_buf_len] = '\0';
378 if(g_buf_len + 1 >= sizeof(g_buf) || ch == '\n' || ch == '\0')
379 {
380
381 /* Send the char */
382
383 if(SH_DoCommand(0x04, (int)g_buf, NULL) != 0)
384 {
385 g_buf_len = 0;
386 return;
387 }
388 else
389 {
390 int i;
391
392 for(i=0; i<g_buf_len; i++)
393 SendChar_ToUART(g_buf[i]);
394 g_buf_len = 0;
395 }
396 }
397 #else
398 SendChar_ToUART(ch);
399 #endif
400 }
401
402
410 char GetChar(void)
411 {
412 #if defined(DEBUG_ENABLE_SEMIHOST)
413 # if defined ( __CC_ARM )
414 int nRet;
415 while(SH_DoCommand(0x101, 0, &nRet) != 0)
416 {
417 if(nRet != 0)
418 {
419 SH_DoCommand(0x07, 0, &nRet);
420 return (char)nRet;
421 }
422 }
423 # else
424 int nRet;
425 while(SH_DoCommand(0x7, 0, &nRet) != 0)
426 {
427 if(nRet != 0)
428 return (char)nRet;
429 }
430 # endif
431 #endif
432 #ifndef DISABLE_UART
433 while (1)
434 {
435 if(!(DEBUG_PORT->FSR & UART_FSR_RX_EMPTY_F_Msk))
436 {
437 return (DEBUG_PORT->RBR);
438
439 }
440 }
441 #else
442 return(0);
443 #endif
444 }
445
446
454 int kbhit(void)
455 {
456 #ifndef DISABLE_UART
457 return !(DEBUG_PORT->FSR & UART_FSR_RX_EMPTY_F_Msk);
458 #else
459 return(0);
460 #endif
461 }
462
470 int IsDebugFifoEmpty(void)
471 {
472 #ifndef DISABLE_UART
473 return (DEBUG_PORT->FSR & UART_FSR_TE_F_Msk) ? 1 : 0;
474 #else
475 return(1);
476 #endif
477
478 }
479
480 /*---------------------------------------------------------------------------------------------------------*/
481 /* C library retargetting */
482 /*---------------------------------------------------------------------------------------------------------*/
483 void _ttywrch(int ch)
484 {
485 SendChar(ch);
486 return;
487 }
488
489 int fputc(int ch, FILE *f)
490 {
491 SendChar(ch);
492 return ch;
493 }
494
495 #if defined (__GNUC__) && !defined(__ARMCC_VERSION)
496
497 int _write (int fd, char *ptr, int len)
498 {
499 int i = len;
500
501 while(i--)
502 {
503 while(DEBUG_PORT->FSR & UART_FSR_TX_FULL_F_Msk);
504
505 DEBUG_PORT->THR = *ptr++;
506
507 if(*ptr == '\n')
508 {
509 while(DEBUG_PORT->FSR & UART_FSR_TX_FULL_F_Msk);
510 DEBUG_PORT->THR = '\r';
511 }
512 }
513 return len;
514 }
515
516 int _read (int fd, char *ptr, int len)
517 {
518
519 while((DEBUG_PORT->FSR & UART_FSR_RX_EMPTY_F_Msk) != 0);
520 *ptr = DEBUG_PORT->RBR;
521 return 1;
522
523
524 }
525
526 #else
527 int fgetc(FILE *f)
528 {
529 return (GetChar());
530 }
531
532
533 int ferror(FILE *f)
534 {
535 return EOF;
536 }
537 #endif
538
539 #ifdef DEBUG_ENABLE_SEMIHOST
540 # ifdef __ICCARM__
541 void __exit(int return_code)
542 {
543
544 /* Check if link with ICE */
545
546 if(SH_DoCommand(0x18, 0x20026, NULL) == 0)
547 {
548 /* Make sure all message is print out */
549
550 while(IsDebugFifoEmpty() == 0);
551 }
552 label:
553 goto label; /* endless loop */
554 }
555 # else
556 void _sys_exit(int return_code)
557 {
558
559 /* Check if link with ICE */
560 if(SH_DoCommand(0x18, 0x20026, NULL) == 0)
561 {
562 /* Make sure all message is print out */
563 while(IsDebugFifoEmpty() == 0);
564 }
565 label:
566 goto label; /* endless loop */
567 }
568 # endif
569 #endif
570 /*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/
571
GetChar
char GetChar(void)
Read a char from debug console.
Definition: retarget.c:410
IsDebugFifoEmpty
int IsDebugFifoEmpty(void)
Check whether UART transmit FIFO is empty or not.
Definition: retarget.c:470
HardFault_Handler
__asm int32_t HardFault_Handler(void)
This HardFault handler is implemented to show r0, r1, r2, r3, r12, lr, pc, psr.
Definition: retarget.c:326
_ttywrch
void _ttywrch(int ch)
Definition: retarget.c:483
DEBUG_PORT
#define DEBUG_PORT
Definition: retarget.c:24
r1
Definition: retarget.c:49
SendChar_ToUART
void SendChar_ToUART(int ch)
Write a char to UART.
Definition: retarget.c:353
UART_FSR_TE_F_Msk
#define UART_FSR_TE_F_Msk
Definition: Nano1X2Series.h:10212
ferror
int ferror(FILE *f)
Definition: retarget.c:533
Hard_Fault_Handler
void Hard_Fault_Handler(uint32_t stack[])
Definition: retarget.c:63
r2
Definition: retarget.c:49
NULL
#define NULL
NULL pointer.
Definition: Nano1X2Series.h:10812
kbhit
int kbhit(void)
Check whether UART receive FIFO is empty or not.
Definition: retarget.c:454
Nano1X2Series.h
Nano102/112 peripheral access layer header file. This file contains all the peripheral register's def...
r3
Definition: retarget.c:49
pc
Definition: retarget.c:49
SendChar
void SendChar(int ch)
Write a char to debug console.
Definition: retarget.c:373
__FILE::handle
int handle
Definition: retarget.c:43
__FILE
Definition: retarget.c:41
r0
Definition: retarget.c:49
fgetc
int fgetc(FILE *f)
Definition: retarget.c:527
r12
Definition: retarget.c:49
UART_FSR_TX_FULL_F_Msk
#define UART_FSR_TX_FULL_F_Msk
Definition: Nano1X2Series.h:10209
stackDump
void stackDump(uint32_t stack[])
Definition: retarget.c:51
UART_FSR_RX_EMPTY_F_Msk
#define UART_FSR_RX_EMPTY_F_Msk
Definition: Nano1X2Series.h:10188
__stdout
FILE __stdout
Definition: retarget.c:46
fputc
int fputc(int ch, FILE *f)
Definition: retarget.c:489
psr
Definition: retarget.c:49
value
return value
Definition: semihosting.h:98
lr
Definition: retarget.c:49
__stdin
FILE __stdin
Definition: retarget.c:47