| NUC029FAE BSP V3.01.002 The Board Support Package for NUC029FAE

retarget.c
Go to the documentation of this file.
1 /**************************************************************************/
12 #include <stdio.h>
13 #include "NUC029FAE.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 /* Un-comment this line to disable all printf and getchar. getchar() will always return 0x00*/
24 //#define DISABLE_UART
25
26 #if defined(DEBUG_ENABLE_SEMIHOST)
27 #ifndef DISABLE_UART
28 #define DISABLE_UART
29 #endif
30 #endif
31
32 /*---------------------------------------------------------------------------------------------------------*/
33 /* Global variables */
34 /*---------------------------------------------------------------------------------------------------------*/
35
36 #if !(defined(__ICCARM__) && (__VER__ >= 6010000))
37 struct __FILE { int handle; /* Add whatever you need here */ };
38 #endif
39 FILE __stdout;
40 FILE __stdin;
41
42 enum { r0, r1, r2, r3, r12, lr, pc, psr};
43
44 void stackDump(uint32_t stack[])
45 {
46 printf("r0 = 0x%x\n", stack[r0]);
47 printf("r1 = 0x%x\n", stack[r1]);
48 printf("r2 = 0x%x\n", stack[r2]);
49 printf("r3 = 0x%x\n", stack[r3]);
50 printf("r12 = 0x%x\n", stack[r12]);
51 printf("lr = 0x%x\n", stack[lr]);
52 printf("pc = 0x%x\n", stack[pc]);
53 printf("psr = 0x%x\n", stack[psr]);
54 }
55
56 void Hard_Fault_Handler(uint32_t stack[])
57 {
58 printf("In Hard Fault Handler\n");
59
60 stackDump(stack);
61
62 //Chip Reset
63 //SYS_UnlockReg();
64 //SYS->IPRSTC1 |= SYS_IPRSTC1_CHIP_RST_Msk;
65
66 while(1);
67 }
68
69
70 #if defined(DEBUG_ENABLE_SEMIHOST)
71 /* The static buffer is used to speed up the semihost */
72 static char g_buf[16];
73 static char g_buf_len = 0;
74
75 /* Make sure won't goes here only because --gnu is defined , so
76 add !__CC_ARM and !__ICCARM__ checking */
77 # if defined ( __GNUC__ ) && !(__CC_ARM) && !(__ICCARM__)
78
79 # elif defined(__ICCARM__)
80
81
92 void HardFault_Handler(void)
93 {
94 asm("MOV R0, lr \n"
95 "LSLS R0, #29 \n" //; Check bit 2
96 "BMI SP_is_PSP \n" //; previous stack is PSP
97 "MRS R0, MSP \n" //; previous stack is MSP, read MSP
98 "B SP_Read_Ready \n"
99 "SP_is_PSP: \n"
100 "MRS R0, PSP \n" //; Read PSP
101 "SP_Read_Ready: \n"
102 "LDR R1, [R0, #24] \n" //; Get previous PC
103 "LDRH R3, [R1] \n" //; Get instruction
104 "LDR R2, [pc, #8] \n" //; The sepcial BKPT instruction
105 "CMP R3, R2 \n" //; Test if the instruction at previous PC is BKPT
106 "BNE HardFault_Handler_Ret\n" //; Not BKPT
107 "ADDS R1, #4 \n" //; Skip BKPT and next line
108 "STR R1, [R0, #24] \n" //; Save previous PC
109 "BX lr \n" //; Return
110 "DCD 0xBEAB \n" //; BKPT instruction code
111 "HardFault_Handler_Ret:\n"
112 "MOVS r0, #4 \n"
113 "MOV r1, LR \n"
114 "TST r0, r1 \n"
115 "BEQ Stack_Use_MSP \n"
116 "MRS R0, PSP \n" //; stack use PSP
117 "B Get_LR_and_Branch \n"
118 "Stack_Use_MSP: \n"
119 "MRS R0, MSP \n" //; stack use MSP
120 "Get_LR_and_Branch: \n"
121 "MOV R1, LR \n" //; LR current value
122 "B Hard_Fault_Handler \n"
123 );
124
125 while(1);
126 }
127
138 int32_t SH_DoCommand(int32_t n32In_R0, int32_t n32In_R1, int32_t *pn32Out_R0)
139 {
140 asm("BKPT 0xAB \n" //; This instruction will cause ICE trap or system HardFault
141 "B SH_ICE \n"
142 "SH_HardFault: \n" //; Captured by HardFault
143 "MOVS R0, #0 \n" //; Set return value to 0
144 "BX lr \n" //; Return
145 "SH_ICE: \n" //; Captured by ICE
146 "CMP R2, #0 \n"
147 "BEQ SH_End \n"
148 "STR R0, [R2]\n" //; Save the return value to *pn32Out_R0
149 "SH_End: \n");
150
151 return 1; //; Return 1 when it is trap by ICE
152
153 }
154
155
156 # else
157
168 __asm int32_t HardFault_Handler(void)
169 {
170
171 MOV R0, LR
172 LSLS R0, #29 //; Check bit 2
173 BMI SP_is_PSP //; previous stack is PSP
174 MRS R0, MSP //; previous stack is MSP, read MSP
175 B SP_Read_Ready
176 SP_is_PSP
177 MRS R0, PSP //; Read PSP
178
179 SP_Read_Ready
180 LDR R1, [R0, #24] //; Get previous PC
181 LDRH R3, [R1] //; Get instruction
182 LDR R2, =0xBEAB //; The sepcial BKPT instruction
183 CMP R3, R2 //; Test if the instruction at previous PC is BKPT
184 BNE HardFault_Handler_Ret //; Not BKPT
185
186 ADDS R1, #4 //; Skip BKPT and next line
187 STR R1, [R0, #24] //; Save previous PC
188
189 BX LR //; Return
190 HardFault_Handler_Ret
191
192 /* TODO: Implement your own hard fault handler here. */
193 MOVS r0, #4
194 MOV r1, LR
195 TST r0, r1
196 BEQ Stack_Use_MSP
197 MRS R0, PSP ;stack use PSP
198 B Get_LR_and_Branch
199 Stack_Use_MSP
200 MRS R0, MSP ; stack use MSP
201 Get_LR_and_Branch
202 MOV R1, LR ; LR current value
203 LDR R2,=__cpp(Hard_Fault_Handler)
204 BX R2
205
206 B .
207
208 ALIGN
209 }
210
221 __asm int32_t SH_DoCommand(int32_t n32In_R0, int32_t n32In_R1, int32_t *pn32Out_R0)
222 {
223 BKPT 0xAB //; Wait ICE or HardFault
224 //; ICE will step over BKPT directly
225 //; HardFault will step BKPT and the next line
226 B SH_ICE
227
228 SH_HardFault //; Captured by HardFault
229 MOVS R0, #0 //; Set return value to 0
230 BX lr //; Return
231
232 SH_ICE //; Captured by ICE
233 //; Save return value
234 CMP R2, #0
235 BEQ SH_End
236 STR R0, [R2] //; Save the return value to *pn32Out_R0
237
238 SH_End
239 MOVS R0, #1 //; Set return value to 1
240 BX lr //; Return
241 }
242 #endif
243
244 #else
245
246 /* Make sure won't goes here only because --gnu is defined , so
247 add !__CC_ARM and !__ICCARM__ checking */
248 # if defined ( __GNUC__ ) && !(__CC_ARM) && !(__ICCARM__)
249
260 void HardFault_Handler(void)
261 {
262 asm("MOVS r0, #4 \n"
263 "MOV r1, LR \n"
264 "TST r0, r1 \n" /*; check LR bit 2 */
265 "BEQ 1f \n" /*; stack use MSP */
266 "MRS R0, PSP \n" /*; stack use PSP, read PSP */
267 "MOV R1, LR \n" /*; LR current value */
268 "B Hard_Fault_Handler \n"
269 "1: \n"
270 "MRS R0, MSP \n" /*; LR current value */
271 "B Hard_Fault_Handler \n"
272 ::[Hard_Fault_Handler] "r" (Hard_Fault_Handler) // input
273 );
274 while(1);
275 }
276
277 # elif defined(__ICCARM__)
278
289 void HardFault_Handler(void)
290 {
291 asm("MOVS r0, #4 \n"
292 "MOV r1, LR \n"
293 "TST r0, r1 \n"
294 "BEQ Stack_Use_MSP \n"
295 "MRS R0, PSP \n" //; stack use PSP
296 "B Get_LR_and_Branch \n"
297 "Stack_Use_MSP: \n"
298 "MRS R0, MSP \n" //; stack use MSP
299 "Get_LR_and_Branch: \n"
300 "MOV R1, LR \n" //; LR current value
301 "B Hard_Fault_Handler \n"
302 );
303
304 while(1);
305 }
306
307 # else
308
319 __asm int32_t HardFault_Handler(void)
320 {
321 MOVS r0, #4
322 MOV r1, LR
323 TST r0, r1
324 BEQ Stack_Use_MSP
325 MRS R0, PSP ;stack use PSP
326 B Get_LR_and_Branch
327 Stack_Use_MSP
328 MRS R0, MSP ; stack use MSP
329 Get_LR_and_Branch
330 MOV R1, LR ; LR current value
331 LDR R2,=__cpp(Hard_Fault_Handler)
332 BX R2
333 }
334
335 #endif
336
337 #endif
338
339
346 void SendChar_ToUART(int ch)
347 {
348 #ifndef DISABLE_UART
349 while(UART->FSR & UART_FSR_TX_FULL_Msk);
350 UART->THR = ch;
351 if(ch == '\n')
352 {
353 while(UART->FSR & UART_FSR_TX_FULL_Msk);
354 UART->THR = '\r';
355 }
356 #endif
357 }
358
359
366 void SendChar(int ch)
367 {
368 #if defined(DEBUG_ENABLE_SEMIHOST)
369 g_buf[g_buf_len++] = ch;
370 g_buf[g_buf_len] = '\0';
371 if(g_buf_len + 1 >= sizeof(g_buf) || ch == '\n' || ch == '\0')
372 {
373
374 /* Send the char */
375
376 if(SH_DoCommand(0x04, (int)g_buf, NULL) != 0)
377 {
378 g_buf_len = 0;
379 return;
380 }
381 else
382 {
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 {
410 if(nRet != 0)
411 {
412 SH_DoCommand(0x07, 0, &nRet);
413 return (char)nRet;
414 }
415 }
416 # else
417 int nRet;
418 while(SH_DoCommand(0x7, 0, &nRet) != 0)
419 {
420 if(nRet != 0)
421 return (char)nRet;
422 }
423 # endif
424 #endif
425 #ifndef DISABLE_UART
426 while (1){
427 if(!(UART->FSR & UART_FSR_RX_EMPTY_Msk))
428 {
429 return (UART->RBR);
430
431 }
432 }
433 #else
434 return(0);
435 #endif
436 }
437
438
446 int kbhit(void)
447 {
448 #ifndef DISABLE_UART
449 return !(UART->FSR & UART_FSR_RX_EMPTY_Msk);
450 #else
451 return(0);
452 #endif
453 }
454
462 int IsDebugFifoEmpty(void)
463 {
464 #ifndef DISABLE_UART
465 return (UART->FSR & UART_FSR_TE_FLAG_Msk) ? 1 : 0;
466 #else
467 return(1);
468 #endif
469
470 }
471
472 /*---------------------------------------------------------------------------------------------------------*/
473 /* C library retargetting */
474 /*---------------------------------------------------------------------------------------------------------*/
475 void _ttywrch(int ch)
476 {
477 SendChar(ch);
478 return;
479 }
480
481 int fputc(int ch, FILE *f)
482 {
483 SendChar(ch);
484 return ch;
485 }
486 #if defined (__GNUC__) && !defined(__ARMCC_VERSION)
487
488 int _write (int fd, char *ptr, int len)
489 {
490 int i = len;
491
492 while(i--) {
493 while(UART->FSR & UART_FSR_TX_FULL_Msk);
494
495 UART->THR = *ptr++;
496
497 if(*ptr == '\n') {
498 while(UART->FSR & UART_FSR_TX_FULL_Msk);
499 UART->THR = '\r';
500 }
501 }
502 return len;
503 }
504
505 int _read (int fd, char *ptr, int len)
506 {
507
508 while((UART->FSR & UART_FSR_RX_EMPTY_Msk) != 0);
509 *ptr = UART->RBR;
510 return 1;
511
512
513 }
514
515 #else
516 int fgetc(FILE *f) {
517 return (GetChar());
518 }
519
520
521 int ferror(FILE *f) {
522 return EOF;
523 }
524 #endif
525 #ifdef DEBUG_ENABLE_SEMIHOST
526 # ifdef __ICCARM__
527 void __exit(int return_code)
528 {
529
530 /* Check if link with ICE */
531
532 if(SH_DoCommand(0x18, 0x20026, NULL) == 0)
533 {
534 /* Make sure all message is print out */
535
536 while(IsDebugFifoEmpty() == 0);
537 }
538 label: goto label; /* endless loop */
539 }
540 # else
541 void _sys_exit(int return_code)
542 {
543
544 /* Check if link with ICE */
545 if(SH_DoCommand(0x18, 0x20026, NULL) == 0)
546 {
547 /* Make sure all message is print out */
548 while(IsDebugFifoEmpty() == 0);
549 }
550 label: goto label; /* endless loop */
551 }
552 # endif
553 #endif
554 /*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/
555
UART
#define UART
Pointer to UART register structure.
Definition: NUC029FAE.h:3223
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:462
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:319
_ttywrch
void _ttywrch(int ch)
Definition: retarget.c:475
NUC029FAE.h
NUC029FAE peripheral access layer header file. This file contains all the peripheral register's defin...
r12
Definition: retarget.c:42
SendChar_ToUART
void SendChar_ToUART(int ch)
Write a char to UART.
Definition: retarget.c:346
ferror
int ferror(FILE *f)
Definition: retarget.c:521
psr
Definition: retarget.c:42
Hard_Fault_Handler
void Hard_Fault_Handler(uint32_t stack[])
Definition: retarget.c:56
r1
Definition: retarget.c:42
r0
Definition: retarget.c:42
NULL
#define NULL
NULL pointer.
Definition: NUC029FAE.h:3389
r3
Definition: retarget.c:42
kbhit
int kbhit(void)
Check whether UART receive FIFO is empty or not.
Definition: retarget.c:446
SendChar
void SendChar(int ch)
Write a char to debug console.
Definition: retarget.c:366
__FILE::handle
int handle
Definition: retarget.c:37
__FILE
Definition: retarget.c:37
r2
Definition: retarget.c:42
fgetc
int fgetc(FILE *f)
Definition: retarget.c:516
stackDump
void stackDump(uint32_t stack[])
Definition: retarget.c:44
__stdout
FILE __stdout
Definition: retarget.c:39
fputc
int fputc(int ch, FILE *f)
Definition: retarget.c:481
value
return value
Definition: semihosting.h:98
__stdin
FILE __stdin
Definition: retarget.c:40
pc
Definition: retarget.c:42
lr
Definition: retarget.c:42