| MINI51DE_BSP V3.02.004 The Board Support Package for Mini51DE Series MCU

retarget.c
Go to the documentation of this file.
1/**************************************************************************/
12#include <stdio.h>
13#include "Mini51Series.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(__ARMCC_VERSION) && (__ARMCC_VERSION < 6040000)) || (defined(__ICCARM__) && (__VER__ >= 8000000))
37 struct __FILE { int handle; /* Add whatever you need here */ };
38#endif
39FILE __stdout;
40FILE __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
138int32_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
176SP_is_PSP
177 MRS R0, PSP //; Read PSP
178
179SP_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
190HardFault_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
199Stack_Use_MSP
200 MRS R0, MSP ; stack use MSP
201Get_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
228SH_HardFault //; Captured by HardFault
229 MOVS R0, #0 //; Set return value to 0
230 BX lr //; Return
231
232SH_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
238SH_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
327Stack_Use_MSP
328 MRS R0, MSP ; stack use MSP
329Get_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 {
494 while(UART->FSR & UART_FSR_TX_FULL_Msk);
495
496 UART->THR = *ptr++;
497
498 if(*ptr == '\n')
499 {
500 while(UART->FSR & UART_FSR_TX_FULL_Msk);
501 UART->THR = '\r';
502 }
503 }
504 return len;
505}
506
507 int _read (int fd, char *ptr, int len)
508{
509
510 while((UART->FSR & UART_FSR_RX_EMPTY_Msk) != 0);
511 *ptr = UART->RBR;
512 return 1;
513
514
515}
516
517#else
518 int fgetc(FILE *f)
519{
520 return (GetChar());
521}
522
523
524 int ferror(FILE *f)
525{
526 return EOF;
527}
528#endif
529#ifdef DEBUG_ENABLE_SEMIHOST
530# ifdef __ICCARM__
531 void __exit(int return_code) {
532
533 /* Check if link with ICE */
534
535 if(SH_DoCommand(0x18, 0x20026, NULL) == 0)
536 {
537 /* Make sure all message is print out */
538
539 while(IsDebugFifoEmpty() == 0);
540 }
541label: goto label; /* endless loop */
542}
543# else
544 void _sys_exit(int return_code) {
545
546 /* Check if link with ICE */
547 if(SH_DoCommand(0x18, 0x20026, NULL) == 0)
548 {
549 /* Make sure all message is print out */
550 while(IsDebugFifoEmpty() == 0);
551 }
552label: goto label; /* endless loop */
553}
554# endif
555#endif
556/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/
557
Mini51Series.h
Mini51 series peripheral access layer header file. This file contains all the peripheral register's d...
UART_FSR_TX_FULL_Msk
#define UART_FSR_TX_FULL_Msk
Definition: Mini51Series.h:5464
UART_FSR_RX_EMPTY_Msk
#define UART_FSR_RX_EMPTY_Msk
Definition: Mini51Series.h:5452
UART_FSR_TE_FLAG_Msk
#define UART_FSR_TE_FLAG_Msk
Definition: Mini51Series.h:5470
UART
#define UART
Pointer to UART register structure.
Definition: Mini51Series.h:5730
NULL
#define NULL
NULL pointer.
Definition: Mini51Series.h:5892
_ttywrch
void _ttywrch(int ch)
Definition: retarget.c:475
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
fgetc
int fgetc(FILE *f)
Definition: retarget.c:518
IsDebugFifoEmpty
int IsDebugFifoEmpty(void)
Check whether UART transmit FIFO is empty or not.
Definition: retarget.c:462
SendChar_ToUART
void SendChar_ToUART(int ch)
Write a char to UART.
Definition: retarget.c:346
ferror
int ferror(FILE *f)
Definition: retarget.c:524
kbhit
int kbhit(void)
Check whether UART receive FIFO is empty or not.
Definition: retarget.c:446
pc
@ pc
Definition: retarget.c:42
r0
@ r0
Definition: retarget.c:42
r2
@ r2
Definition: retarget.c:42
lr
@ lr
Definition: retarget.c:42
r3
@ r3
Definition: retarget.c:42
r1
@ r1
Definition: retarget.c:42
r12
@ r12
Definition: retarget.c:42
psr
@ psr
Definition: retarget.c:42
fputc
int fputc(int ch, FILE *f)
Definition: retarget.c:481
__stdin
FILE __stdin
Definition: retarget.c:40
Hard_Fault_Handler
void Hard_Fault_Handler(uint32_t stack[])
Definition: retarget.c:56
SendChar
void SendChar(int ch)
Write a char to debug console.
Definition: retarget.c:366
__stdout
FILE __stdout
Definition: retarget.c:39
GetChar
char GetChar(void)
Read a char from debug console.
Definition: retarget.c:403
stackDump
void stackDump(uint32_t stack[])
Definition: retarget.c:44
value
return value
Definition: semihosting.h:98