NANO100_BSP V3.04.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(__ARMCC_VERSION) && (__ARMCC_VERSION < 6040000)) || (defined(__ICCARM__) && (__VER__ >= 8000000))
41struct __FILE {
42 int handle; /* Add whatever you need here */
43};
44#endif
47
48enum { r0, r1, r2, r3, r12, lr, pc, psr};
49
50void 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
62void 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 */
78static char g_buf[16];
79static 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
97void 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
143int32_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
181SP_is_PSP
182 MRS R0, PSP //; Read PSP
183
184SP_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
195HardFault_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
204Stack_Use_MSP
205 MRS R0, MSP ; stack use MSP
206Get_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
233SH_HardFault //; Captured by HardFault
234 MOVS R0, #0 //; Set return value to 0
235 BX lr //; Return
236
237SH_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
243SH_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
265void 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
294void 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
332Stack_Use_MSP
333 MRS R0, MSP ; stack use MSP
334Get_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
351void SendChar_ToUART(int ch)
352{
353#ifndef DISABLE_UART
355 DEBUG_PORT->THR = ch;
356 if(ch == '\n') {
358 DEBUG_PORT->THR = '\r';
359 }
360#endif
361}
362
363
370void 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
403char 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
442int 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
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/*---------------------------------------------------------------------------------------------------------*/
471void _ttywrch(int ch)
472{
473 SendChar(ch);
474 return;
475}
476
477int fputc(int ch, FILE *f)
478{
479 SendChar(ch);
480 return ch;
481}
482
483#if defined ( __GNUC__ )
484
485int _write (int fd, char *ptr, int len)
486{
487 int i = len;
488
489 while(i--) {
491
492 DEBUG_PORT->THR = *ptr++;
493
494 if(*ptr == '\n') {
496 DEBUG_PORT->THR = '\r';
497 }
498 }
499 return len;
500}
501
502int _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
513int fgetc(FILE *f)
514{
515 return (GetChar());
516}
517
518
519int ferror(FILE *f)
520{
521 return EOF;
522}
523#endif
524#ifdef DEBUG_ENABLE_SEMIHOST
525# ifdef __ICCARM__
526void __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 }
536label:
537 goto label; /* endless loop */
538}
539# else
540void _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 }
548label:
549 goto label; /* endless loop */
550}
551# endif
552#endif
553/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/
554
Nano100 series peripheral access layer header file. This file contains all the peripheral register's ...
#define UART_FSR_TX_FULL_F_Msk
#define UART_FSR_RX_EMPTY_F_Msk
#define UART_FSR_TE_F_Msk
#define R3
Definition: SDCard.h:53
#define R2
Definition: SDCard.h:52
#define R1
Definition: SDCard.h:50
#define NULL
NULL pointer.
void _ttywrch(int ch)
Definition: retarget.c:471
__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
int fgetc(FILE *f)
Definition: retarget.c:513
int IsDebugFifoEmpty(void)
Check whether UART transmit FIFO is empty or not.
Definition: retarget.c:458
void SendChar_ToUART(int ch)
Write a char to UART.
Definition: retarget.c:351
int ferror(FILE *f)
Definition: retarget.c:519
int kbhit(void)
Check whether UART receive FIFO is empty or not.
Definition: retarget.c:442
int fputc(int ch, FILE *f)
Definition: retarget.c:477
FILE __stdin
Definition: retarget.c:46
void Hard_Fault_Handler(uint32_t stack[])
Definition: retarget.c:62
void SendChar(int ch)
Write a char to debug console.
Definition: retarget.c:370
FILE __stdout
Definition: retarget.c:45
char GetChar(void)
Read a char from debug console.
Definition: retarget.c:403
#define DEBUG_PORT
Definition: retarget.c:24
@ pc
Definition: retarget.c:48
@ r0
Definition: retarget.c:48
@ r2
Definition: retarget.c:48
@ lr
Definition: retarget.c:48
@ r3
Definition: retarget.c:48
@ r1
Definition: retarget.c:48
@ r12
Definition: retarget.c:48
@ psr
Definition: retarget.c:48
void stackDump(uint32_t stack[])
Definition: retarget.c:50
return value
Definition: semihosting.h:98