]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/ColdFire_MCF52221_CodeWarrior/sources/uart_support.c
commit 9f316c246baafa15c542a5aea81a94f26e3d6507
[freertos] / FreeRTOS / Demo / ColdFire_MCF52221_CodeWarrior / sources / uart_support.c
1 /*\r
2  * File:        uart_support.c\r
3  * Purpose:     Implements UART basic support, Derivative Specific Interrupt handler and need function needed \r
4  *              for MSL Support (printf\cout to terminal), defined in <UART.h>\r
5  *\r
6  * Notes:       \r
7  *              \r
8  */\r
9 #include "support_common.h"\r
10 #include "uart_support.h"\r
11 \r
12 #if ENABLE_UART_SUPPORT==1\r
13 \r
14 \r
15 #if UART_SUPPORT_TYPE==UART_PSC\r
16 /* 5475 & 5485 boards have different names for uart access registers */\r
17 void uart_init(int channel, unsigned long systemClockKHz, unsigned long baudRate)\r
18 {\r
19         register uint16 ubgs;\r
20 \r
21         /* \r
22          * On Verdi, only PSC 0 & 1 are brought out to RS232 transceivers\r
23          */\r
24 \r
25         /* Put PSC in UART mode */\r
26         MCF_PSC_PSCSICR(channel) = MCF_PSC_PSCSICR_SIM_UART;\r
27 \r
28         /* Rx and Tx baud rate from timers */\r
29         MCF_PSC_PSCCSR(channel) = (0\r
30                 | MCF_PSC_PSCCSR_RCSEL_SYS_CLK \r
31                 | MCF_PSC_PSCCSR_TCSEL_SYS_CLK);\r
32 \r
33         /*\r
34          * Calculate baud settings\r
35          */\r
36         ubgs = (uint16)((systemClockKHz * 1000)/(baudRate * 32));\r
37 \r
38         MCF_PSC_PSCCTUR(channel) =  (uint8) ((ubgs >> 8) & 0xFF);\r
39         MCF_PSC_PSCCTLR(channel) =  (uint8) (ubgs & 0xFF);\r
40 \r
41         /* Reset transmitter, receiver, mode register, and error conditions */\r
42         MCF_PSC_PSCCR(channel) = MCF_PSC_PSCCR_RESET_RX;\r
43         MCF_PSC_PSCCR(channel) = MCF_PSC_PSCCR_RESET_TX;\r
44         MCF_PSC_PSCCR(channel) = MCF_PSC_PSCCR_RESET_ERROR;\r
45         MCF_PSC_PSCCR(channel) = MCF_PSC_PSCCR_RESET_BKCHGINT;\r
46         MCF_PSC_PSCCR(channel) = MCF_PSC_PSCCR_RESET_MR;\r
47 \r
48         /* 8-bit data, no parity */\r
49         MCF_PSC_PSCMR(channel) = (0\r
50 #ifdef UART_HARDWARE_FLOW_CONTROL\r
51                 | MCF_PSC_PSCMR_RXRTS\r
52 #endif\r
53                 | MCF_PSC_PSCMR_PM_NONE\r
54                 | MCF_PSC_PSCMR_BC_8);\r
55 \r
56         /* No echo or loopback, 1 stop bit */\r
57         MCF_PSC_PSCMR(channel) = (0\r
58 #ifdef UART_HARDWARE_FLOW_CONTROL\r
59                 | MCF_PSC_PSCMR_TXCTS\r
60 #endif \r
61                 | MCF_PSC_PSCMR_CM_NORMAL\r
62                 | MCF_PSC_PSCMR_SB_STOP_BITS_1);\r
63 \r
64         /* Mask all UART interrupts */\r
65         MCF_PSC_PSCIMR(channel) = 0x0000;\r
66 \r
67         /* Enable RTS to send */\r
68         MCF_PSC_PSCOPSET(channel) = MCF_PSC_PSCOPSET_RTS;\r
69 \r
70         /* Setup FIFO Alarms */\r
71         MCF_PSC_PSCRFAR(channel) = MCF_PSC_PSCRFAR_ALARM(248);\r
72         MCF_PSC_PSCTFAR(channel) = MCF_PSC_PSCTFAR_ALARM(248);\r
73 \r
74         /* Enable receiver and transmitter */\r
75         MCF_PSC_PSCCR(channel) =(0\r
76                 | MCF_PSC_PSCCR_RX_ENABLED\r
77                 | MCF_PSC_PSCCR_TX_ENABLED);\r
78 }\r
79 \r
80 /********************************************************************/\r
81 /*\r
82  * Wait for a character to be received on the specified UART\r
83  *\r
84  * Return Values:\r
85  *  the received character\r
86  */\r
87 char uart_getchar (int channel)\r
88 {\r
89         /* Wait until character has been received */\r
90         while (!(MCF_PSC_PSCSR(channel) & MCF_PSC_PSCSR_RXRDY))\r
91         {\r
92         \r
93         }\r
94         return (char)(*((uint8 *) &MCF_PSC_PSCRB_8BIT(channel)));\r
95 }\r
96 \r
97 /********************************************************************/\r
98 /*\r
99  * Wait for space in the UART Tx FIFO and then send a character\r
100  */ \r
101 void uart_putchar (int channel, char ch)\r
102 {\r
103         /* Wait until space is available in the FIFO */\r
104         while (!(MCF_PSC_PSCSR(channel) & MCF_PSC_PSCSR_TXRDY))\r
105                 ;\r
106         *((uint8 *) &MCF_PSC_PSCTB_8BIT(channel)) = (uint8)ch;\r
107 }\r
108 \r
109 \r
110 #else /* UART_SUPPORT_TYPE==UART_PSC */\r
111 \r
112 #if UART_SUPPORT_TYPE == UART_5407\r
113 /********************************************************************/\r
114 /* \r
115  * 5407 derivative doesn't have macros to access URB/UTB by channel number \r
116  * because they have different sizes for UART0 & UART1\r
117  * But in UART mode only 8 bits of UART1 URB/UTB is used, so define these macros here\r
118  *  if they doesn't defined before\r
119  */\r
120 #ifndef MCF_UART_URB\r
121 #define MCF_UART_URB(x)                      (*(vuint8 *)(&__MBAR[0x1CC + ((x)*0x40)]))\r
122 #endif /* MCF_UART_URB */\r
123 \r
124 #ifndef MCF_UART_UTB\r
125 #define MCF_UART_UTB(x)                      (*(vuint8 *)(&__MBAR[0x1CC + ((x)*0x40)]))\r
126 #endif /* MCF_UART_UTB */\r
127 \r
128 #endif /* UART_SUPPORT_TYPE == UART_5407 */\r
129 \r
130 void uart_init(int channel, unsigned long systemClockKHz, unsigned long baudRate)\r
131 {\r
132         /*\r
133          * Initialize UART for serial communications\r
134          */\r
135 \r
136         register uint16 ubgs;\r
137 \r
138 #if UART_SUPPORT_TYPE==UART_54451\r
139         uint32 vco;\r
140         uint32 divider;\r
141         uint32 bus_clk;\r
142 \r
143         divider = ((MCF_CLOCK_PCR & 0x000000F0) >> 4) + 1;\r
144         vco = ((MCF_CLOCK_PCR >> 24) * systemClockKHz * 1000);\r
145         bus_clk = (vco / divider);\r
146 #endif\r
147         /*\r
148          * Reset Transmitter\r
149          */\r
150         MCF_UART_UCR(channel) = MCF_UART_UCR_RESET_TX;\r
151 \r
152         /*\r
153          * Reset Receiver\r
154          */\r
155         MCF_UART_UCR(channel) = MCF_UART_UCR_RESET_RX;\r
156 \r
157         /*\r
158          * Reset Mode Register\r
159          */\r
160         MCF_UART_UCR(channel) = MCF_UART_UCR_RESET_MR;\r
161 \r
162         /*\r
163          * No parity, 8-bits per character\r
164          */\r
165         MCF_UART_UMR(channel) = (0\r
166                 | MCF_UART_UMR_PM_NONE\r
167                 | MCF_UART_UMR_BC_8 );\r
168 \r
169         /*\r
170          * No echo or loopback, 1 stop bit\r
171          */\r
172         MCF_UART_UMR(channel) = (0\r
173                 | MCF_UART_UMR_CM_NORMAL\r
174                 | MCF_UART_UMR_SB_STOP_BITS_1);\r
175 \r
176         /*\r
177          * Set Rx and Tx baud by SYSTEM CLOCK\r
178          */\r
179         MCF_UART_UCSR(channel) = (0\r
180                 | MCF_UART_UCSR_RCS_SYS_CLK\r
181                 | MCF_UART_UCSR_TCS_SYS_CLK);\r
182 \r
183         /*\r
184          * Mask all UART interrupts\r
185          */\r
186         MCF_UART_UIMR(channel) = 0;\r
187 \r
188         /*\r
189          * Calculate baud settings\r
190          */\r
191 #if UART_SUPPORT_TYPE==UART_54451\r
192         ubgs = (uint16)(((bus_clk >> 5) + (baudRate >> 1)) / baudRate);\r
193 #else\r
194         ubgs = (uint16)((systemClockKHz * 1000)/(baudRate * 32));\r
195 #endif\r
196 \r
197 #if UART_SUPPORT_TYPE==UART_DIVIDER || UART_SUPPORT_TYPE == UART_5407\r
198         MCF_UART_UDU(channel) = (uint8)((ubgs & 0xFF00) >> 8);\r
199         MCF_UART_UDL(channel) = (uint8)(ubgs & 0x00FF);\r
200 #else /* UART_SUPPORT_TYPE!=UART_DIVIDER */\r
201         MCF_UART_UBG1(channel) = (uint8)((ubgs & 0xFF00) >> 8);\r
202         MCF_UART_UBG2(channel) = (uint8)(ubgs & 0x00FF);\r
203 #endif /* UART_SUPPORT_TYPE==UART_DIVIDER */\r
204 \r
205         /*\r
206          * Enable receiver and transmitter\r
207          */\r
208         MCF_UART_UCR(channel) = (0\r
209                 | MCF_UART_UCR_TX_ENABLED\r
210                 | MCF_UART_UCR_RX_ENABLED);\r
211 }\r
212 \r
213 /********************************************************************/\r
214 /*\r
215  * Wait for a character to be received on the specified UART\r
216  *\r
217  * Return Values:\r
218  *  the received character\r
219  */\r
220 char uart_getchar (int channel)\r
221 {\r
222     /* Wait until character has been received */\r
223     while (!(MCF_UART_USR(channel) & MCF_UART_USR_RXRDY)) \r
224     {\r
225         \r
226     };\r
227 \r
228     return (char)MCF_UART_URB(channel);\r
229 }\r
230 \r
231 /********************************************************************/\r
232 /*\r
233  * Wait for space in the UART Tx FIFO and then send a character\r
234  */ \r
235 void uart_putchar (int channel, char ch)\r
236 {\r
237     /* Wait until space is available in the FIFO */\r
238     while (!(MCF_UART_USR(channel) & MCF_UART_USR_TXRDY)) \r
239     {\r
240         \r
241     };\r
242 \r
243     /* Send the character */\r
244     MCF_UART_UTB(channel) = (uint8)ch;\r
245 }\r
246 \r
247 #endif /* UART_SUPPORT_TYPE==UART_PSC */\r
248 /********************************************************************/\r
249 \r
250 /********************************************************************/\r
251 /** <UART.h> Neeeded functions                                     **/\r
252 /********************************************************************/\r
253 \r
254 /****************************************************************************/\r
255 /*\r
256  * Implementation for CodeWarror MSL interface to serial device (UART.h). \r
257  * Needed for printf, etc...\r
258  * Only InitializeUART, ReadUARTN, and WriteUARTN are implemented.\r
259  *\r
260  */\r
261 UARTError InitializeUART(UARTBaudRate baudRate)\r
262 {\r
263 #if UART_SUPPORT_TYPE==UART_54451\r
264         baudRate = kBaud115200;\r
265 #endif\r
266         uart_init(TERMINAL_PORT, SYSTEM_CLOCK_KHZ, baudRate);\r
267         return kUARTNoError;\r
268 }\r
269 \r
270 /****************************************************************************/\r
271 /*\r
272         ReadUARTN\r
273         \r
274         Read N bytes from the UART.\r
275         \r
276         bytes                   pointer to result buffer\r
277         limit                   size of buffer and # of bytes to read\r
278 */\r
279 /****************************************************************************/\r
280 UARTError ReadUARTN(void* bytes, unsigned long limit)\r
281 {\r
282         int count;\r
283         for (count = 0; count < limit; count++) {\r
284         *( (char *)bytes + count ) = uart_getchar(TERMINAL_PORT);\r
285         }\r
286         return kUARTNoError;\r
287 }\r
288 \r
289 /****************************************************************************/\r
290 UARTError WriteUARTN(const void* bytes, unsigned long length)\r
291 {\r
292         int count;\r
293         for (count = 0; count < length; count++) {\r
294                 uart_putchar(TERMINAL_PORT, *( ((char *)bytes) + count));\r
295         }\r
296         return kUARTNoError;\r
297 }\r
298 #endif /* ENABLE_UART_SUPPORT */\r