1 /*******************************************************************************
2  * (c) Copyright 2013 Microsemi SoC Products Group.  All rights reserved.
3  *
4  * Redirection of the standard library I/O to one of the SmartFusion2
5  * MMUART.
6  *
7  * SVN $Revision: 7375 $
8  * SVN $Date: 2015-05-01 14:57:40 +0100 (Fri, 01 May 2015) $
9  */
10 
11 /*==============================================================================
12  * The content of this source file will only be compiled if either one of the
13  * following two defined symbols are defined in the project settings:
14  *  - MICROSEMI_STDIO_THRU_MMUART0
15  *  - MICROSEMI_STDIO_THRU_MMUART1
16  *
17  */
18 #ifdef MICROSEMI_STDIO_THRU_MMUART0
19 #ifndef MICROSEMI_STDIO_THRU_UART
20 #define MICROSEMI_STDIO_THRU_UART
21 #endif
22 #endif  /* MICROSEMI_STDIO_THRU_MMUART0 */
23 
24 #ifdef MICROSEMI_STDIO_THRU_MMUART1
25 #ifndef MICROSEMI_STDIO_THRU_UART
26 #define MICROSEMI_STDIO_THRU_UART
27 #endif
28 #endif  /* MICROSEMI_STDIO_THRU_MMUART1 */
29 
30 /*==============================================================================
31  * Actual implementation.
32  */
33 #ifdef MICROSEMI_STDIO_THRU_UART
34 
35 #include <stdio.h>
36 #include <rt_misc.h>
37 
38 #include "m2sxxx.h"
39 #include "mss_uart.h"
40 #include "core_uart_apb.h"
41 
42 
43 /*
44  * The baud rate will default to 57600 baud if no baud rate is specified though the
45  * MICROSEMI_STDIO_BAUD_RATE define.
46  */
47 #ifndef MICROSEMI_STDIO_BAUD_RATE
48 #define MICROSEMI_STDIO_BAUD_RATE  MSS_UART_115200_BAUD
49 #endif
50 
51 #ifdef MICROSEMI_STDIO_THRU_MMUART0
52 static mss_uart_instance_t * const gp_my_uart = &g_mss_uart0;
53 #else
54 static mss_uart_instance_t * const gp_my_uart = &g_mss_uart1;
55 #endif
56 
57 /*==============================================================================
58  * Flag used to indicate if the UART driver needs to be initialized.
59  */
60 static int g_stdio_uart_init_done = 0;
61 
62 
63 #define LSR_THRE_MASK   0x20u
64 
65 /*
66  * Disable semihosting apis
67  */
68 #pragma import(__use_no_semihosting_swi)
69 
70 /*==============================================================================
71  * sendchar()
72  */
sendchar(int ch)73 int sendchar(int ch)
74 {
75     uint32_t tx_ready;
76     //第一次调用时,初始化串口
77     if(!g_stdio_uart_init_done)
78     {
79         MSS_UART_init(gp_my_uart,
80                       MICROSEMI_STDIO_BAUD_RATE,
81                       MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY);
82         g_stdio_uart_init_done = 1;
83     }
84     do {
85         tx_ready = gp_my_uart->hw_reg->LSR & LSR_THRE_MASK;
86     } while(!tx_ready);
87     gp_my_uart->hw_reg->THR = ch;
88     return (ch);
89 }
90 
91 /*==============================================================================
92  *
93  */
94 struct __FILE { int handle; /* Add whatever you need here */ };
95 FILE __stdout;
96 FILE __stdin;
97 
98 
99 /*==============================================================================
100  * fputc()
101  */
fputc(int ch,FILE * f)102 int fputc(int ch, FILE *f)
103 {
104   return (sendchar(ch));
105 }
106 
107 /*==============================================================================
108  * fgetc()
109  */
fgetc(FILE * f)110 int fgetc(FILE *f)
111 {
112     uint8_t rx_size;
113     uint8_t rx_byte;
114 
115     do {
116         rx_size = MSS_UART_get_rx(gp_my_uart, &rx_byte, 1);
117     } while(0u == rx_size);
118 
119     return rx_byte;
120 }
121 
122 /*==============================================================================
123  * ferror()
124  */
ferror(FILE * f)125 int ferror(FILE *f)
126 {
127   /* Your implementation of ferror */
128   return EOF;
129 }
130 
131 /*==============================================================================
132  * _ttywrch()
133  */
_ttywrch(int ch)134 void _ttywrch(int ch)
135 {
136   sendchar(ch);
137 }
138 
139 /*==============================================================================
140  * _sys_exit()
141  */
_sys_exit(int return_code)142 void _sys_exit(int return_code)
143 {
144     for(;;)
145     {
146         ;  /* endless loop */
147     }
148 }
149 
150 #endif  /* MICROSEMI_STDIO_THRU_UART */
151