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

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