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