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 
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 
char GetChar(void)
Read a char from debug console.
Definition: retarget.c:407
int IsDebugFifoEmpty(void)
Check whether UART transmit FIFO is empty or not.
Definition: retarget.c:466
__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
void _ttywrch(int ch)
Definition: retarget.c:479
#define DEBUG_PORT
Definition: retarget.c:24
Definition: retarget.c:47
void SendChar_ToUART(int ch)
Write a char to UART.
Definition: retarget.c:350
#define UART_FSR_RX_EMPTY_F_Msk
int ferror(FILE *f)
Definition: retarget.c:527
void Hard_Fault_Handler(uint32_t stack[])
Definition: retarget.c:61
Nano100 series peripheral access layer header file. This file contains all the peripheral register's ...
#define NULL
NULL pointer.
#define R2
Definition: SDCard.h:52
Definition: retarget.c:47
int kbhit(void)
Check whether UART receive FIFO is empty or not.
Definition: retarget.c:450
Definition: retarget.c:47
#define UART_FSR_TE_F_Msk
Definition: retarget.c:47
void SendChar(int ch)
Write a char to debug console.
Definition: retarget.c:370
int handle
Definition: retarget.c:41
Definition: retarget.c:47
#define R1
Definition: SDCard.h:50
int fgetc(FILE *f)
Definition: retarget.c:521
Definition: retarget.c:47
void stackDump(uint32_t stack[])
Definition: retarget.c:49
FILE __stdout
Definition: retarget.c:44
int fputc(int ch, FILE *f)
Definition: retarget.c:485
Definition: retarget.c:47
#define R3
Definition: SDCard.h:53
return value
Definition: semihosting.h:98
Definition: retarget.c:47
FILE __stdin
Definition: retarget.c:45
#define UART_FSR_TX_FULL_F_Msk