1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2007 Catalin Patulea <cat@vv.carleton.ca>
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
26 #include "uart-target.h"
28 #define MAX_UART_BUFFER 31
29 #define SEND_RING_SIZE 256
30 #define RECEIVE_RING_SIZE 20
33 uart1_send_buffer_ring
[SEND_RING_SIZE
],
34 uart1_receive_buffer_ring
[RECEIVE_RING_SIZE
];
36 static volatile int uart1_send_count
, uart1_send_read
, uart1_send_write
;
37 static volatile int uart1_receive_count
, uart1_receive_read
, uart1_receive_write
;
41 /* Enable UART clock */
42 bitset16(&IO_CLK_MOD2
, CLK_MOD2_UART1
);
45 IO_UART1_MSR
= 0xC400;
46 IO_UART1_BRSR
= 0x0057;
47 IO_UART1_RFCR
= 0x8020; /* Trigger later */
48 IO_UART1_TFCR
= 0x0000; /* Trigger level */
50 /* init the receive buffer */
51 uart1_receive_count
=0;
53 uart1_receive_write
=0;
55 /* init the send buffer */
60 /* Enable the interrupt */
61 bitset16(&IO_INTC_EINT0
, INTR_EINT0_UART1
);
64 /* This function is not interrupt driven */
65 void uart1_putc(char ch
)
67 /* Wait for the interupt driven puts to finish */
68 while(uart1_send_count
>0);
70 /* Wait for room in FIFO */
71 while ((IO_UART1_TFCR
& 0x3f) >= 0x20);
77 void uart1_puts(const char *str
, int size
)
79 if(size
>SEND_RING_SIZE
)
80 panicf("Too much data passed to uart1_puts");
82 /* Wait for the previous transfer to finish */
83 while(uart1_send_count
>0);
85 memcpy(uart1_send_buffer_ring
, str
, size
);
87 /* Disable interrupt while modifying the pointers */
88 bitclr16(&IO_INTC_EINT0
, INTR_EINT0_UART1
);
90 uart1_send_count
=size
;
93 /* prime the hardware buffer */
94 while(((IO_UART1_TFCR
& 0x3f) < 0x20) && (uart1_send_count
> 0))
96 IO_UART1_DTRR
=uart1_send_buffer_ring
[uart1_send_read
++];
100 /* Enable interrupt */
101 bitset16(&IO_INTC_EINT0
, INTR_EINT0_UART1
);
104 void uart1_clear_queue(void)
106 /* Disable interrupt while modifying the pointers */
107 bitclr16(&IO_INTC_EINT0
, INTR_EINT0_UART1
);
109 uart1_receive_write
=0;
110 uart1_receive_count
=0;
111 uart1_receive_read
=0;
113 /* Enable interrupt */
114 bitset16(&IO_INTC_EINT0
, INTR_EINT0_UART1
);
117 /* This function returns the number of bytes left in the queue after a read is done (negative if fail)*/
118 int uart1_gets_queue(char *str
, int size
)
120 /* Disable the interrupt while modifying the pointers */
121 bitclr16(&IO_INTC_EINT0
, INTR_EINT0_UART1
);
124 if(uart1_receive_count
<size
)
130 if(uart1_receive_read
+size
<=RECEIVE_RING_SIZE
)
132 memcpy(str
,uart1_receive_buffer_ring
+uart1_receive_read
,size
);
134 uart1_receive_read
+=size
;
138 int tempcount
=(RECEIVE_RING_SIZE
-uart1_receive_read
);
139 memcpy(str
,uart1_receive_buffer_ring
+uart1_receive_read
,tempcount
);
140 memcpy(str
+tempcount
,uart1_receive_buffer_ring
,size
-tempcount
);
142 uart1_receive_read
=size
-tempcount
;
145 uart1_receive_count
-=size
;
147 retval
=uart1_receive_count
;
150 /* Enable the interrupt */
151 bitset16(&IO_INTC_EINT0
, INTR_EINT0_UART1
);
156 /* UART1 receive/transmit interupt handler */
159 IO_INTC_IRQ0
= INTR_IRQ0_UART1
; /* Clear the interrupt first */
160 while (IO_UART1_RFCR
& 0x3f)
162 if (uart1_receive_count
> RECEIVE_RING_SIZE
)
163 panicf("UART1 receive buffer overflow");
166 if(uart1_receive_write
>=RECEIVE_RING_SIZE
)
167 uart1_receive_write
=0;
169 uart1_receive_buffer_ring
[uart1_receive_write
]=IO_UART1_DTRR
& 0xff;
170 uart1_receive_write
++;
171 uart1_receive_count
++;
175 while ( ((IO_UART1_TFCR
& 0x3f) < 0x20) && (uart1_send_count
> 0) )
177 IO_UART1_DTRR
=uart1_send_buffer_ring
[uart1_send_read
++];