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