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
9 #include "support_common.h"
\r
10 #include "uart_support.h"
\r
12 #if ENABLE_UART_SUPPORT==1
\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
19 register uint16 ubgs;
\r
22 * On Verdi, only PSC 0 & 1 are brought out to RS232 transceivers
\r
25 /* Put PSC in UART mode */
\r
26 MCF_PSC_PSCSICR(channel) = MCF_PSC_PSCSICR_SIM_UART;
\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
34 * Calculate baud settings
\r
36 ubgs = (uint16)((systemClockKHz * 1000)/(baudRate * 32));
\r
38 MCF_PSC_PSCCTUR(channel) = (uint8) ((ubgs >> 8) & 0xFF);
\r
39 MCF_PSC_PSCCTLR(channel) = (uint8) (ubgs & 0xFF);
\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
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
53 | MCF_PSC_PSCMR_PM_NONE
\r
54 | MCF_PSC_PSCMR_BC_8);
\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
61 | MCF_PSC_PSCMR_CM_NORMAL
\r
62 | MCF_PSC_PSCMR_SB_STOP_BITS_1);
\r
64 /* Mask all UART interrupts */
\r
65 MCF_PSC_PSCIMR(channel) = 0x0000;
\r
67 /* Enable RTS to send */
\r
68 MCF_PSC_PSCOPSET(channel) = MCF_PSC_PSCOPSET_RTS;
\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
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
80 /********************************************************************/
\r
82 * Wait for a character to be received on the specified UART
\r
85 * the received character
\r
87 char uart_getchar (int channel)
\r
89 /* Wait until character has been received */
\r
90 while (!(MCF_PSC_PSCSR(channel) & MCF_PSC_PSCSR_RXRDY))
\r
94 return (char)(*((uint8 *) &MCF_PSC_PSCRB_8BIT(channel)));
\r
97 /********************************************************************/
\r
99 * Wait for space in the UART Tx FIFO and then send a character
\r
101 void uart_putchar (int channel, char ch)
\r
103 /* Wait until space is available in the FIFO */
\r
104 while (!(MCF_PSC_PSCSR(channel) & MCF_PSC_PSCSR_TXRDY))
\r
106 *((uint8 *) &MCF_PSC_PSCTB_8BIT(channel)) = (uint8)ch;
\r
110 #else /* UART_SUPPORT_TYPE==UART_PSC */
\r
112 #if UART_SUPPORT_TYPE == UART_5407
\r
113 /********************************************************************/
\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
120 #ifndef MCF_UART_URB
\r
121 #define MCF_UART_URB(x) (*(vuint8 *)(&__MBAR[0x1CC + ((x)*0x40)]))
\r
122 #endif /* MCF_UART_URB */
\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
128 #endif /* UART_SUPPORT_TYPE == UART_5407 */
\r
130 void uart_init(int channel, unsigned long systemClockKHz, unsigned long baudRate)
\r
133 * Initialize UART for serial communications
\r
136 register uint16 ubgs;
\r
138 #if UART_SUPPORT_TYPE==UART_54451
\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
148 * Reset Transmitter
\r
150 MCF_UART_UCR(channel) = MCF_UART_UCR_RESET_TX;
\r
155 MCF_UART_UCR(channel) = MCF_UART_UCR_RESET_RX;
\r
158 * Reset Mode Register
\r
160 MCF_UART_UCR(channel) = MCF_UART_UCR_RESET_MR;
\r
163 * No parity, 8-bits per character
\r
165 MCF_UART_UMR(channel) = (0
\r
166 | MCF_UART_UMR_PM_NONE
\r
167 | MCF_UART_UMR_BC_8 );
\r
170 * No echo or loopback, 1 stop bit
\r
172 MCF_UART_UMR(channel) = (0
\r
173 | MCF_UART_UMR_CM_NORMAL
\r
174 | MCF_UART_UMR_SB_STOP_BITS_1);
\r
177 * Set Rx and Tx baud by SYSTEM CLOCK
\r
179 MCF_UART_UCSR(channel) = (0
\r
180 | MCF_UART_UCSR_RCS_SYS_CLK
\r
181 | MCF_UART_UCSR_TCS_SYS_CLK);
\r
184 * Mask all UART interrupts
\r
186 MCF_UART_UIMR(channel) = 0;
\r
189 * Calculate baud settings
\r
191 #if UART_SUPPORT_TYPE==UART_54451
\r
192 ubgs = (uint16)(((bus_clk >> 5) + (baudRate >> 1)) / baudRate);
\r
194 ubgs = (uint16)((systemClockKHz * 1000)/(baudRate * 32));
\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
206 * Enable receiver and transmitter
\r
208 MCF_UART_UCR(channel) = (0
\r
209 | MCF_UART_UCR_TX_ENABLED
\r
210 | MCF_UART_UCR_RX_ENABLED);
\r
213 /********************************************************************/
\r
215 * Wait for a character to be received on the specified UART
\r
218 * the received character
\r
220 char uart_getchar (int channel)
\r
222 /* Wait until character has been received */
\r
223 while (!(MCF_UART_USR(channel) & MCF_UART_USR_RXRDY))
\r
228 return (char)MCF_UART_URB(channel);
\r
231 /********************************************************************/
\r
233 * Wait for space in the UART Tx FIFO and then send a character
\r
235 void uart_putchar (int channel, char ch)
\r
237 /* Wait until space is available in the FIFO */
\r
238 while (!(MCF_UART_USR(channel) & MCF_UART_USR_TXRDY))
\r
243 /* Send the character */
\r
244 MCF_UART_UTB(channel) = (uint8)ch;
\r
247 #endif /* UART_SUPPORT_TYPE==UART_PSC */
\r
248 /********************************************************************/
\r
250 /********************************************************************/
\r
251 /** <UART.h> Neeeded functions **/
\r
252 /********************************************************************/
\r
254 /****************************************************************************/
\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
261 UARTError InitializeUART(UARTBaudRate baudRate)
\r
263 #if UART_SUPPORT_TYPE==UART_54451
\r
264 baudRate = kBaud115200;
\r
266 uart_init(TERMINAL_PORT, SYSTEM_CLOCK_KHZ, baudRate);
\r
267 return kUARTNoError;
\r
270 /****************************************************************************/
\r
274 Read N bytes from the UART.
\r
276 bytes pointer to result buffer
\r
277 limit size of buffer and # of bytes to read
\r
279 /****************************************************************************/
\r
280 UARTError ReadUARTN(void* bytes, unsigned long limit)
\r
283 for (count = 0; count < limit; count++) {
\r
284 *( (char *)bytes + count ) = uart_getchar(TERMINAL_PORT);
\r
286 return kUARTNoError;
\r
289 /****************************************************************************/
\r
290 UARTError WriteUARTN(const void* bytes, unsigned long length)
\r
293 for (count = 0; count < length; count++) {
\r
294 uart_putchar(TERMINAL_PORT, *( ((char *)bytes) + count));
\r
296 return kUARTNoError;
\r
298 #endif /* ENABLE_UART_SUPPORT */
\r