MINI58_BSP V3.01.005
The Board Support Package for Mini58 Series MCU
retarget.c
Go to the documentation of this file.
1/**************************************************************************/
12#include <stdio.h>
13#include "Mini58Series.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#ifdef DEBUG_ENABLE_UART1
24#define DEBUG_PORT UART1
25#else
26#define DEBUG_PORT UART0
27#endif
28
29/* Un-comment this line to disable all printf and getchar. getchar() will always return 0x00*/
30//#define DISABLE_UART
31
32#if defined(DEBUG_ENABLE_SEMIHOST)
33 #ifndef DISABLE_UART
34 #define DISABLE_UART
35 #endif
36#endif
37
38/*---------------------------------------------------------------------------------------------------------*/
39/* Global variables */
40/*---------------------------------------------------------------------------------------------------------*/
41#if (defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 6040000)) || (defined(__ICCARM__) && (__VER__ >= 8000000))
42struct __FILE { int handle; /* Add whatever you need here */ };
43#endif
46
47enum { r0, r1, r2, r3, r12, lr, pc, psr};
48
49void 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
61void 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->IPRSTC1 |= SYS_IPRSTC1_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 */
77static char g_buf[16];
78static 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
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 special 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 special 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
354 while(DEBUG_PORT->FIFOSTS & UART_FIFOSTS_TXFULL_Msk);
355 DEBUG_PORT->DAT = ch;
356 if(ch == '\n')
357 {
358 while(DEBUG_PORT->FIFOSTS & UART_FIFOSTS_TXFULL_Msk);
359 DEBUG_PORT->DAT = '\r';
360 }
361#endif
362}
363
364
371void SendChar(int ch)
372{
373#if defined(DEBUG_ENABLE_SEMIHOST)
374 g_buf[g_buf_len++] = ch;
375 g_buf[g_buf_len] = '\0';
376 if(g_buf_len + 1 >= sizeof(g_buf) || ch == '\n' || ch == '\0')
377 {
378
379 /* Send the char */
380
381 if(SH_DoCommand(0x04, (int)g_buf, NULL) != 0)
382 {
383 g_buf_len = 0;
384 return;
385 }
386 else
387 {
388 int i;
389
390 for(i=0;i<g_buf_len;i++)
391 SendChar_ToUART(g_buf[i]);
392 g_buf_len = 0;
393 }
394 }
395#else
396 SendChar_ToUART(ch);
397#endif
398}
399
400
408char GetChar(void)
409{
410#if defined(DEBUG_ENABLE_SEMIHOST)
411# if defined ( __CC_ARM )
412 int nRet;
413 while(SH_DoCommand(0x101, 0, &nRet) != 0)
414 {
415 if(nRet != 0)
416 {
417 SH_DoCommand(0x07, 0, &nRet);
418 return (char)nRet;
419 }
420 }
421# else
422 int nRet;
423 while(SH_DoCommand(0x7, 0, &nRet) != 0)
424 {
425 if(nRet != 0)
426 return (char)nRet;
427 }
428# endif
429#endif
430#ifndef DISABLE_UART
431 while (1){
432 if(!(DEBUG_PORT->FIFOSTS & UART_FIFOSTS_RXEMPTY_Msk))
433 {
434 return (DEBUG_PORT->DAT);
435
436 }
437 }
438#else
439 return(0);
440#endif
441}
442
443
451int kbhit(void)
452{
453#ifndef DISABLE_UART
454 return !(DEBUG_PORT->FIFOSTS & UART_FIFOSTS_RXEMPTY_Msk);
455#else
456 return(0);
457#endif
458}
459
468{
469#ifndef DISABLE_UART
470 return (DEBUG_PORT->FIFOSTS & UART_FIFOSTS_TXEMPTYF_Msk) ? 1 : 0;
471#else
472 return(1);
473#endif
474
475}
476
477/*---------------------------------------------------------------------------------------------------------*/
478/* C library retargetting */
479/*---------------------------------------------------------------------------------------------------------*/
480void _ttywrch(int ch)
481{
482 SendChar(ch);
483 return;
484}
485
486int fputc(int ch, FILE *f)
487{
488 SendChar(ch);
489 return ch;
490}
491#if defined (__GNUC__) && !defined(__ARMCC_VERSION)
492
493int _write (int fd, char *ptr, int len)
494{
495 int i = len;
496#ifndef DISABLE_UART
497 while(i--)
498 {
499 while(DEBUG_PORT->FIFOSTS & UART_FIFOSTS_TXFULL_Msk);
500
501 DEBUG_PORT->DAT = *ptr++;
502
503 if(*ptr == '\n')
504 {
505 while(DEBUG_PORT->FIFOSTS & UART_FIFOSTS_TXFULL_Msk);
506 DEBUG_PORT->DAT = '\r';
507 }
508 }
509#endif
510 return len;
511}
512
513int _read (int fd, char *ptr, int len)
514{
515#ifndef DISABLE_UART
516 while((DEBUG_PORT->FIFOSTS & UART_FIFOSTS_RXEMPTY_Msk) != 0);
517 *ptr = DEBUG_PORT->DAT;
518 return 1;
519#else
520 return 0;
521#endif
522
523}
524
525#else
526int fgetc(FILE *f)
527{
528 return (GetChar());
529}
530
531
532int ferror(FILE *f)
533{
534 return EOF;
535}
536#endif
537#ifdef DEBUG_ENABLE_SEMIHOST
538# ifdef __ICCARM__
539void __exit(int return_code)
540{
541
542 /* Check if link with ICE */
543
544 if(SH_DoCommand(0x18, 0x20026, NULL) == 0)
545 {
546 /* Make sure all message is print out */
547
548 while(IsDebugFifoEmpty() == 0);
549 }
550label: goto label; /* endless loop */
551}
552# else
553void _sys_exit(int return_code)
554{
555
556 /* Check if link with ICE */
557 if(SH_DoCommand(0x18, 0x20026, NULL) == 0)
558 {
559 /* Make sure all message is print out */
560 while(IsDebugFifoEmpty() == 0);
561 }
562label: goto label; /* endless loop */
563}
564# endif
565#endif
566
567
Mini58 series peripheral access layer header file. This file contains all the peripheral register's d...
#define UART_FIFOSTS_TXFULL_Msk
#define UART_FIFOSTS_TXEMPTYF_Msk
#define UART_FIFOSTS_RXEMPTY_Msk
#define NULL
NULL pointer.
@ pc
Definition: retarget.c:47
@ r0
Definition: retarget.c:47
@ r2
Definition: retarget.c:47
@ lr
Definition: retarget.c:47
@ r3
Definition: retarget.c:47
@ r1
Definition: retarget.c:47
@ r12
Definition: retarget.c:47
@ psr
Definition: retarget.c:47
void _ttywrch(int ch)
Definition: retarget.c:480
__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:526
int IsDebugFifoEmpty(void)
Check whether UART transmit FIFO is empty or not.
Definition: retarget.c:467
void SendChar_ToUART(int ch)
Write a char to UART.
Definition: retarget.c:351
int ferror(FILE *f)
Definition: retarget.c:532
int kbhit(void)
Check whether UART receive FIFO is empty or not.
Definition: retarget.c:451
int fputc(int ch, FILE *f)
Definition: retarget.c:486
FILE __stdin
Definition: retarget.c:45
void Hard_Fault_Handler(uint32_t stack[])
Definition: retarget.c:61
void SendChar(int ch)
Write a char to debug console.
Definition: retarget.c:371
FILE __stdout
Definition: retarget.c:44
char GetChar(void)
Read a char from debug console.
Definition: retarget.c:408
#define DEBUG_PORT
Definition: retarget.c:26
void stackDump(uint32_t stack[])
Definition: retarget.c:49
return value
Definition: semihosting.h:98