Mercurial > ecos-v2_0-branch
annotate packages/io/serial/current/src/mn10300/mn10300_serial.c @ 62:7a6ac9edc838 ecos-sw-2000-01-24
Merge from eCos master repository on 2000-01-24-19:43:49-GMT
| author | jlarmour |
|---|---|
| date | Mon, 24 Jan 2000 21:43:17 +0000 |
| parents | 5af43b635655 |
| children | c38311975d4f |
| rev | line source |
|---|---|
| 2 | 1 //========================================================================== |
| 2 // | |
| 3 // mn10300_serial.c | |
| 4 // | |
| 5 // Serial device driver for mn10300 on-chip serial devices | |
| 6 // | |
| 7 //========================================================================== | |
| 8 //####COPYRIGHTBEGIN#### | |
| 9 // | |
| 10 // ------------------------------------------- | |
| 11 // The contents of this file are subject to the Cygnus eCos Public License | |
| 12 // Version 1.0 (the "License"); you may not use this file except in | |
| 13 // compliance with the License. You may obtain a copy of the License at | |
| 14 // http://sourceware.cygnus.com/ecos | |
| 15 // | |
| 16 // Software distributed under the License is distributed on an "AS IS" | |
| 17 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the | |
| 18 // License for the specific language governing rights and limitations under | |
| 19 // the License. | |
| 20 // | |
| 21 // The Original Code is eCos - Embedded Cygnus Operating System, released | |
| 22 // September 30, 1998. | |
| 23 // | |
| 24 // The Initial Developer of the Original Code is Cygnus. Portions created | |
| 25 // by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved. | |
| 26 // ------------------------------------------- | |
| 27 // | |
| 28 //####COPYRIGHTEND#### | |
| 29 //========================================================================== | |
| 30 //#####DESCRIPTIONBEGIN#### | |
| 31 // | |
| 32 // Author(s): nickg | |
| 33 // Contributors: nickg | |
| 34 // Date: 1999-02-25 | |
| 35 // Purpose: MN10300 serial device driver | |
| 36 // Description: MN10300 serial device driver | |
| 37 // | |
| 38 //####DESCRIPTIONEND#### | |
| 39 // | |
| 40 //========================================================================== | |
| 41 | |
| 42 #include <pkgconf/hal.h> | |
| 43 #include <pkgconf/io_serial.h> | |
| 44 #include <cyg/hal/hal_io.h> | |
| 45 | |
| 46 #include <cyg/io/io.h> | |
| 47 #include <cyg/io/devtab.h> | |
| 48 #include <cyg/io/serial.h> | |
| 49 #include <cyg/hal/hal_intr.h> | |
| 50 | |
| 51 #ifdef CYGPKG_IO_SERIAL_MN10300 | |
| 52 | |
|
32
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
53 #define CYG_HAL_MN10300_SERIAL_RX_FIFO |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
54 |
| 2 | 55 //------------------------------------------------------------------------- |
| 56 | |
| 57 extern void diag_printf(const char *fmt, ...); | |
| 58 | |
| 59 //------------------------------------------------------------------------- | |
| 60 // Forward definitions | |
| 61 | |
| 62 static bool mn10300_serial_init(struct cyg_devtab_entry *tab); | |
| 63 static bool mn10300_serial_putc(serial_channel *chan, unsigned char c); | |
| 64 static Cyg_ErrNo mn10300_serial_lookup(struct cyg_devtab_entry **tab, | |
| 65 struct cyg_devtab_entry *sub_tab, | |
| 66 const char *name); | |
| 67 static unsigned char mn10300_serial_getc(serial_channel *chan); | |
| 68 static bool mn10300_serial_set_config(serial_channel *chan, cyg_serial_info_t *config); | |
| 69 static void mn10300_serial_start_xmit(serial_channel *chan); | |
| 70 static void mn10300_serial_stop_xmit(serial_channel *chan); | |
| 71 | |
| 72 #ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE | |
| 73 static cyg_uint32 mn10300_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data); | |
| 74 static cyg_uint32 mn10300_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data); | |
| 75 static void mn10300_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data); | |
| 76 static void mn10300_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data); | |
| 77 #endif | |
| 78 | |
| 79 //------------------------------------------------------------------------- | |
| 80 | |
| 81 #define BUFSIZE 128 | |
| 82 | |
| 83 //------------------------------------------------------------------------- | |
| 84 // MN10300 serial line control register values: | |
| 85 | |
| 86 // Offsets to serial control registers from base | |
| 87 #define SERIAL_CTR 0x0 | |
| 88 #define SERIAL_ICR 0x4 | |
| 89 #define SERIAL_TXB 0x8 | |
| 90 #define SERIAL_RXB 0x9 | |
| 91 #define SERIAL_STR 0xc | |
| 92 #define SERIAL_TIM 0xd | |
| 93 | |
| 94 // Status register bits | |
| 95 #define SR_RBF 0x10 | |
| 96 #define SR_TBF 0x20 | |
| 97 #define SR_RXF 0x40 | |
| 98 #define SR_TXF 0x80 | |
| 99 | |
| 100 // Control register bits | |
| 101 #define LCR_SB1 0x00 | |
| 102 #define LCR_SB1_5 0x00 | |
| 103 #define LCR_SB2 0x04 | |
| 104 #define LCR_PN 0x00 // Parity mode - none | |
| 105 #define LCR_PS 0x40 // Forced "space" parity | |
| 106 #define LCR_PM 0x50 // Forced "mark" parity | |
| 107 #define LCR_PE 0x60 // Parity mode - even | |
| 108 #define LCR_PO 0x70 // Parity mode - odd | |
| 109 #define LCR_WL5 0x00 // not supported - use 7bit | |
| 110 #define LCR_WL6 0x00 // not supported - use 7bit | |
| 111 #define LCR_WL7 0x00 // 7 bit chars | |
| 112 #define LCR_WL8 0x80 // 8 bit chars | |
| 113 #define LCR_RXE 0x4000 // receive enable | |
| 114 #define LCR_TXE 0x8000 // transmit enable | |
|
30
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
115 |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
116 #if defined(CYG_HAL_MN10300_AM31) |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
117 #define LCR_TWE 0x0100 // interrupt enable (only on serial2/AM31) |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
118 #else |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
119 #define LCR_TWE 0x0000 // Bit does not exist in other variants |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
120 #endif |
| 2 | 121 |
| 122 //------------------------------------------------------------------------- | |
| 123 // MN10300 timer registers: | |
| 124 | |
| 125 #undef TIMER_BR | |
| 126 #undef TIMER_MD | |
| 127 #define TIMER_MD 0x00 | |
| 128 #define TIMER_BR 0x10 | |
| 129 | |
| 130 //------------------------------------------------------------------------- | |
|
30
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
131 // Serial and timer base registers: |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
132 |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
133 #if defined(CYG_HAL_MN10300_AM31) |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
134 |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
135 #define SERIAL0_BASE 0x34000800 |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
136 #define SERIAL1_BASE 0x34000810 |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
137 #define SERIAL2_BASE 0x34000820 |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
138 |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
139 #define TIMER0_BASE 0x34001000 |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
140 #define TIMER1_BASE 0x34001001 |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
141 #define TIMER2_BASE 0x34001002 |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
142 |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
143 #define SERIAL0_TIMER_SELECT 0x0004 // timer 0 |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
144 #define SERIAL1_TIMER_SELECT 0x0004 // timer 1 |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
145 #define SERIAL2_TIMER_SELECT 0x0001 // timer 2 |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
146 |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
147 #ifdef CYG_HAL_MN10300_AM31_STDEVAL1 |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
148 // The use of PORT3 to provide CTS/CTR is specific to |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
149 // the STDEVAL1 board only. |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
150 #define PORT3_MD 0x36008025 |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
151 #endif |
| 2 | 152 |
|
30
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
153 #define ENABLE_TRANSMIT_INTERRUPT(mn10300_chan) \ |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
154 CYG_MACRO_START \ |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
155 if( mn10300_chan->is_serial2 ) \ |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
156 cr |= LCR_TWE; \ |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
157 else \ |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
158 cr |= LCR_TXE; \ |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
159 CYG_MACRO_END |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
160 |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
161 #define DISABLE_TRANSMIT_INTERRUPT(mn10300_chan) \ |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
162 CYG_MACRO_START \ |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
163 if( mn10300_chan->is_serial2 ) \ |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
164 cr &= ~LCR_TWE; \ |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
165 else \ |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
166 cr &= ~LCR_TXE; \ |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
167 CYG_MACRO_END |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
168 |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
169 #else |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
170 |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
171 #error Unsupported MN10300 variant |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
172 |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
173 #endif |
| 2 | 174 |
| 175 //------------------------------------------------------------------------- | |
| 176 // Tables to map input values to hardware settings | |
| 177 | |
| 178 static unsigned char select_word_length[] = { | |
| 179 LCR_WL5, // 5 bits / word (char) | |
| 180 LCR_WL6, | |
| 181 LCR_WL7, | |
| 182 LCR_WL8 | |
| 183 }; | |
| 184 | |
| 185 static unsigned char select_stop_bits[] = { | |
| 186 0, | |
| 187 LCR_SB1, // 1 stop bit | |
| 188 LCR_SB1_5, // 1.5 stop bit | |
| 189 LCR_SB2 // 2 stop bits | |
| 190 }; | |
| 191 | |
| 192 static unsigned char select_parity[] = { | |
| 193 LCR_PN, // No parity | |
| 194 LCR_PE, // Even parity | |
| 195 LCR_PO, // Odd parity | |
| 196 LCR_PM, // Mark parity | |
| 197 LCR_PS, // Space parity | |
| 198 }; | |
| 199 | |
|
30
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
200 #if defined(CYG_HAL_MN10300_AM31) |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
201 |
| 2 | 202 static unsigned short select_baud_01[] = { |
| 203 0, // Unused | |
| 204 0, // 50 | |
| 205 0, // 75 | |
| 206 0, // 110 | |
| 207 0, // 134.5 | |
| 208 0, // 150 | |
| 209 0, // 200 | |
| 210 0, // 300 | |
| 211 0, // 600 | |
| 212 0, // 1200 | |
| 213 0, // 1800 | |
| 214 0, // 2400 | |
| 215 0, // 3600 | |
| 216 0, // 4800 | |
| 217 0, // 7200 | |
| 218 195, // 9600 | |
| 219 130, // 14400 | |
| 220 98, // 19200 | |
| 221 48, // 38400 | |
| 222 32, // 57600 | |
| 223 16, // 115200 | |
| 224 8, // 230400 | |
| 225 }; | |
| 226 | |
| 227 // Serial 2 has its own timer register in addition to using timer 2 to | |
| 228 // supply the baud rate generator. Both of these must be proframmed to | |
| 229 // get the right baud rate. The following values come from Matsushita | |
| 230 // with some modifications from Cygmon. | |
| 231 static struct | |
| 232 { | |
| 233 cyg_uint8 serial2_val; | |
| 234 cyg_uint8 timer2_val; | |
| 235 } select_baud_2[] = { | |
| 236 { 0, 0 }, // Unused | |
| 237 { 0, 0 }, // 50 | |
| 238 { 0, 0 }, // 75 | |
| 239 { 0, 0 }, // 110 | |
| 240 { 0, 0 }, // 134.5 | |
| 241 { 0, 0 }, // 150 | |
| 242 { 0, 0 }, // 200 | |
| 243 { 0, 0 }, // 300 | |
| 244 { 126, 196 }, // 600 | |
| 245 { 125, 98 }, // 1200 | |
| 246 { 0, 0 }, // 1800 | |
| 247 { 124, 49 }, // 2400 | |
| 248 { 0, 0 }, // 3600 | |
| 249 { 124, 24 }, // 4800 | |
| 250 { 0, 0 }, // 7200 | |
| 251 { 70, 21 }, // 9600 | |
| 252 { 0, 0 }, // 14400 | |
| 253 { 70, 10 }, // 19200 | |
| 254 { 22, 16 }, // 38400 | |
| 255 { 88, 2 }, // 57600 | |
| 256 { 64, 1 }, // 115200 | |
| 257 { 62, 0 }, // 230400 | |
| 258 }; | |
| 259 | |
|
30
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
260 #else |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
261 |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
262 #error Unsupported MN10300 variant |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
263 |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
264 #endif |
| 2 | 265 |
| 266 //------------------------------------------------------------------------- | |
| 267 // Info for each serial device controlled | |
| 268 | |
| 269 typedef struct mn10300_serial_info { | |
|
32
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
270 CYG_ADDRWORD base; |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
271 CYG_ADDRWORD timer_base; |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
272 CYG_WORD timer_select; |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
273 CYG_WORD rx_int; |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
274 CYG_WORD tx_int; |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
275 cyg_bool is_serial2; |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
276 cyg_interrupt rx_interrupt; |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
277 cyg_interrupt tx_interrupt; |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
278 cyg_handle_t rx_interrupt_handle; |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
279 cyg_handle_t tx_interrupt_handle; |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
280 #ifdef CYG_HAL_MN10300_SERIAL_RX_FIFO |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
281 volatile cyg_int32 fifo_head; |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
282 volatile cyg_int32 fifo_tail; |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
283 volatile cyg_uint8 fifo[16]; |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
284 #endif |
| 2 | 285 } mn10300_serial_info; |
| 286 | |
| 287 //------------------------------------------------------------------------- | |
| 288 // Callback functions exported by this driver | |
| 289 | |
| 290 static SERIAL_FUNS(mn10300_serial_funs, | |
| 291 mn10300_serial_putc, | |
| 292 mn10300_serial_getc, | |
| 293 mn10300_serial_set_config, | |
| 294 mn10300_serial_start_xmit, | |
| 295 mn10300_serial_stop_xmit | |
| 296 ); | |
| 297 | |
| 298 //------------------------------------------------------------------------- | |
| 299 // Hardware info for each serial line | |
| 300 | |
| 301 #ifndef CYG_HAL_MN10300_STDEVAL1 | |
| 302 #ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL0 | |
| 303 static mn10300_serial_info mn10300_serial_info0 = { | |
|
30
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
304 SERIAL0_BASE, |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
305 TIMER0_BASE, |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
306 SERIAL0_TIMER_SELECT, |
| 2 | 307 CYGNUM_HAL_INTERRUPT_SERIAL_0_RX, |
| 308 CYGNUM_HAL_INTERRUPT_SERIAL_0_TX, | |
| 309 false | |
| 310 }; | |
| 311 #if CYGNUM_IO_SERIAL_MN10300_SERIAL0_BUFSIZE > 0 | |
| 312 static unsigned char mn10300_serial_out_buf0[CYGNUM_IO_SERIAL_MN10300_SERIAL0_BUFSIZE]; | |
| 313 static unsigned char mn10300_serial_in_buf0[CYGNUM_IO_SERIAL_MN10300_SERIAL0_BUFSIZE]; | |
| 314 #endif | |
| 315 #endif // CYGPKG_IO_SERIAL_MN10300_SERIAL0 | |
| 316 #endif | |
| 317 | |
| 318 #ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL1 | |
| 319 static mn10300_serial_info mn10300_serial_info1 = { | |
|
30
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
320 SERIAL1_BASE, |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
321 TIMER1_BASE, |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
322 SERIAL1_TIMER_SELECT, |
| 2 | 323 CYGNUM_HAL_INTERRUPT_SERIAL_1_RX, |
| 324 CYGNUM_HAL_INTERRUPT_SERIAL_1_TX, | |
| 325 false | |
| 326 }; | |
| 327 #if CYGNUM_IO_SERIAL_MN10300_SERIAL1_BUFSIZE > 0 | |
| 328 static unsigned char mn10300_serial_out_buf1[CYGNUM_IO_SERIAL_MN10300_SERIAL1_BUFSIZE]; | |
| 329 static unsigned char mn10300_serial_in_buf1[CYGNUM_IO_SERIAL_MN10300_SERIAL1_BUFSIZE]; | |
| 330 #endif | |
| 331 #endif // CYGPKG_IO_SERIAL_MN10300_SERIAL1 | |
| 332 | |
| 333 #ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL2 | |
| 334 static mn10300_serial_info mn10300_serial_info2 = { | |
|
30
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
335 SERIAL2_BASE, |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
336 TIMER2_BASE, |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
337 SERIAL2_TIMER_SELECT, |
| 2 | 338 CYGNUM_HAL_INTERRUPT_SERIAL_2_RX, |
| 339 CYGNUM_HAL_INTERRUPT_SERIAL_2_TX, | |
| 340 true | |
| 341 }; | |
| 342 #if CYGNUM_IO_SERIAL_MN10300_SERIAL2_BUFSIZE > 0 | |
| 343 static unsigned char mn10300_serial_out_buf2[CYGNUM_IO_SERIAL_MN10300_SERIAL2_BUFSIZE]; | |
| 344 static unsigned char mn10300_serial_in_buf2[CYGNUM_IO_SERIAL_MN10300_SERIAL2_BUFSIZE]; | |
| 345 #endif | |
| 346 #endif // CYGPKG_IO_SERIAL_MN10300_SERIAL2 | |
| 347 | |
| 348 | |
| 349 //------------------------------------------------------------------------- | |
| 350 // Channel descriptions: | |
| 351 | |
| 352 #ifdef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE | |
| 353 #define SIZEOF_BUF(_x_) 0 | |
| 354 #else | |
| 355 #define SIZEOF_BUF(_x_) sizeof(_x_) | |
| 356 #endif | |
| 357 | |
| 358 #ifndef CYG_HAL_MN10300_STDEVAL1 | |
| 359 #ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL0 | |
| 360 #if CYGNUM_IO_SERIAL_MN10300_SERIAL0_BUFSIZE > 0 | |
| 361 static SERIAL_CHANNEL_USING_INTERRUPTS(mn10300_serial_channel0, | |
| 362 mn10300_serial_funs, | |
| 363 mn10300_serial_info0, | |
| 364 CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MN10300_SERIAL0_BAUD), | |
| 365 CYG_SERIAL_STOP_DEFAULT, | |
| 366 CYG_SERIAL_PARITY_DEFAULT, | |
| 367 CYG_SERIAL_WORD_LENGTH_DEFAULT, | |
| 368 CYG_SERIAL_FLAGS_DEFAULT, | |
| 369 &mn10300_serial_out_buf0[0], | |
| 370 SIZEOF_BUF(mn10300_serial_out_buf0), | |
| 371 &mn10300_serial_in_buf0[0], | |
| 372 SIZEOF_BUF(mn10300_serial_in_buf0) | |
| 373 ); | |
| 374 #else | |
| 375 static SERIAL_CHANNEL(mn10300_serial_channel0, | |
| 376 mn10300_serial_funs, | |
| 377 mn10300_serial_info0, | |
| 378 CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MN10300_SERIAL0_BAUD), | |
| 379 CYG_SERIAL_STOP_DEFAULT, | |
| 380 CYG_SERIAL_PARITY_DEFAULT, | |
| 381 CYG_SERIAL_WORD_LENGTH_DEFAULT, | |
| 382 CYG_SERIAL_FLAGS_DEFAULT | |
| 383 ); | |
| 384 #endif | |
| 385 #endif // CYGPKG_IO_SERIAL_MN10300_SERIAL0 | |
| 386 #endif | |
| 387 | |
| 388 #ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL1 | |
| 389 #if CYGNUM_IO_SERIAL_MN10300_SERIAL1_BUFSIZE > 0 | |
| 390 static SERIAL_CHANNEL_USING_INTERRUPTS(mn10300_serial_channel1, | |
| 391 mn10300_serial_funs, | |
| 392 mn10300_serial_info1, | |
| 393 CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MN10300_SERIAL1_BAUD), | |
| 394 CYG_SERIAL_STOP_DEFAULT, | |
| 395 CYG_SERIAL_PARITY_DEFAULT, | |
| 396 CYG_SERIAL_WORD_LENGTH_DEFAULT, | |
| 397 CYG_SERIAL_FLAGS_DEFAULT, | |
| 398 &mn10300_serial_out_buf1[0], | |
| 399 SIZEOF_BUF(mn10300_serial_out_buf1), | |
| 400 &mn10300_serial_in_buf1[0], | |
| 401 SIZEOF_BUF(mn10300_serial_in_buf1) | |
| 402 ); | |
| 403 #else | |
| 404 static SERIAL_CHANNEL(mn10300_serial_channel1, | |
| 405 mn10300_serial_funs, | |
| 406 mn10300_serial_info1, | |
| 407 CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MN10300_SERIAL1_BAUD), | |
| 408 CYG_SERIAL_STOP_DEFAULT, | |
| 409 CYG_SERIAL_PARITY_DEFAULT, | |
| 410 CYG_SERIAL_WORD_LENGTH_DEFAULT, | |
| 411 CYG_SERIAL_FLAGS_DEFAULT | |
| 412 ); | |
| 413 #endif | |
| 414 #endif // CYGPKG_IO_SERIAL_MN10300_SERIAL1 | |
| 415 | |
| 416 #ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL2 | |
| 417 #if CYGNUM_IO_SERIAL_MN10300_SERIAL2_BUFSIZE > 0 | |
| 418 static SERIAL_CHANNEL_USING_INTERRUPTS(mn10300_serial_channel2, | |
| 419 mn10300_serial_funs, | |
| 420 mn10300_serial_info2, | |
| 421 CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MN10300_SERIAL2_BAUD), | |
| 422 CYG_SERIAL_STOP_DEFAULT, | |
| 423 CYG_SERIAL_PARITY_DEFAULT, | |
| 424 CYG_SERIAL_WORD_LENGTH_DEFAULT, | |
| 425 CYG_SERIAL_FLAGS_DEFAULT, | |
| 426 &mn10300_serial_out_buf2[0], | |
| 427 SIZEOF_BUF(mn10300_serial_out_buf2), | |
| 428 &mn10300_serial_in_buf2[0], | |
| 429 SIZEOF_BUF(mn10300_serial_in_buf2) | |
| 430 ); | |
| 431 #else | |
| 432 static SERIAL_CHANNEL(mn10300_serial_channel2, | |
| 433 mn10300_serial_funs, | |
| 434 mn10300_serial_info2, | |
| 435 CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MN10300_SERIAL2_BAUD), | |
| 436 CYG_SERIAL_STOP_DEFAULT, | |
| 437 CYG_SERIAL_PARITY_DEFAULT, | |
| 438 CYG_SERIAL_WORD_LENGTH_DEFAULT, | |
| 439 CYG_SERIAL_FLAGS_DEFAULT | |
| 440 ); | |
| 441 #endif | |
| 442 #endif // CYGPKG_IO_SERIAL_MN10300_SERIAL2 | |
| 443 | |
| 444 //------------------------------------------------------------------------- | |
| 445 // And finally, the device table entries: | |
| 446 | |
| 447 #ifndef CYG_HAL_MN10300_STDEVAL1 | |
| 448 #ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL0 | |
| 449 // On the standard eval board serial0 is not connected. If enabled, it | |
| 450 // generates continuous frame error and overrun interrupts. Hence we do | |
| 451 // not touch it. | |
| 452 DEVTAB_ENTRY(mn10300_serial_io0, | |
| 453 CYGDAT_IO_SERIAL_MN10300_SERIAL0_NAME, | |
| 454 0, // Does not depend on a lower level interface | |
|
62
7a6ac9edc838
Merge from eCos master repository on 2000-01-24-19:43:49-GMT
jlarmour
parents:
32
diff
changeset
|
455 &cyg_io_serial_devio, |
| 2 | 456 mn10300_serial_init, |
| 457 mn10300_serial_lookup, // Serial driver may need initializing | |
| 458 &mn10300_serial_channel0 | |
| 459 ); | |
| 460 #endif // CYGPKG_IO_SERIAL_MN10300_SERIAL0 | |
| 461 #endif | |
| 462 | |
| 463 #ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL1 | |
| 464 DEVTAB_ENTRY(mn10300_serial_io1, | |
| 465 CYGDAT_IO_SERIAL_MN10300_SERIAL1_NAME, | |
| 466 0, // Does not depend on a lower level interface | |
|
62
7a6ac9edc838
Merge from eCos master repository on 2000-01-24-19:43:49-GMT
jlarmour
parents:
32
diff
changeset
|
467 &cyg_io_serial_devio, |
| 2 | 468 mn10300_serial_init, |
| 469 mn10300_serial_lookup, // Serial driver may need initializing | |
| 470 &mn10300_serial_channel1 | |
| 471 ); | |
| 472 #endif // CYGPKG_IO_SERIAL_MN10300_SERIAL1 | |
| 473 | |
| 474 #ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL2 | |
| 475 DEVTAB_ENTRY(mn10300_serial_io2, | |
| 476 CYGDAT_IO_SERIAL_MN10300_SERIAL2_NAME, | |
| 477 0, // Does not depend on a lower level interface | |
|
62
7a6ac9edc838
Merge from eCos master repository on 2000-01-24-19:43:49-GMT
jlarmour
parents:
32
diff
changeset
|
478 &cyg_io_serial_devio, |
| 2 | 479 mn10300_serial_init, |
| 480 mn10300_serial_lookup, // Serial driver may need initializing | |
| 481 &mn10300_serial_channel2 | |
| 482 ); | |
| 483 #endif // CYGPKG_IO_SERIAL_MN10300_SERIAL2 | |
| 484 | |
| 485 //------------------------------------------------------------------------- | |
| 486 // Read the serial line's status register. Serial 2 has an 8 bit status | |
| 487 // register while serials 0 and 1 have 16 bit registers. This function | |
| 488 // uses the correct size access, but passes back a 16 bit quantity for | |
| 489 // both. | |
| 490 | |
| 491 static cyg_uint16 mn10300_read_sr( mn10300_serial_info *mn10300_chan ) | |
| 492 { | |
| 493 cyg_uint16 sr = 0; | |
| 494 if( mn10300_chan->is_serial2 ) | |
| 495 { | |
| 496 cyg_uint8 sr8; | |
| 497 HAL_READ_UINT8(mn10300_chan->base+SERIAL_STR, sr8); | |
| 498 sr = sr8; | |
| 499 } | |
| 500 else | |
| 501 { | |
| 502 HAL_READ_UINT16(mn10300_chan->base+SERIAL_STR, sr); | |
| 503 } | |
| 504 | |
| 505 return sr; | |
| 506 } | |
| 507 | |
| 508 //------------------------------------------------------------------------- | |
| 509 | |
| 510 static bool | |
| 511 mn10300_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init) | |
| 512 { | |
| 513 mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; | |
| 514 cyg_uint16 cr = 0; | |
|
10
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
4
diff
changeset
|
515 cyg_uint16 sr; |
|
30
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
516 |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
517 // wait for the device to become quiescent. This could take some time |
|
10
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
4
diff
changeset
|
518 // if the device had been transmitting at a low baud rate. |
|
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
4
diff
changeset
|
519 do { |
|
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
4
diff
changeset
|
520 sr = mn10300_read_sr(mn10300_chan); |
|
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
4
diff
changeset
|
521 } while (sr & (SR_RXF|SR_TXF)); |
| 2 | 522 |
| 523 // Disable device entirely. | |
| 524 HAL_WRITE_UINT16(mn10300_chan->base+SERIAL_CTR, 0); | |
|
10
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
4
diff
changeset
|
525 |
|
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
4
diff
changeset
|
526 // Set up the Interrupt Mode Register |
| 2 | 527 HAL_WRITE_UINT8(mn10300_chan->base+SERIAL_ICR, 0); |
| 528 | |
| 529 // Set up baud rate | |
| 530 if( mn10300_chan->is_serial2 ) | |
| 531 { | |
| 532 // Serial 2 is a bit different from 0 and 1 in the way that the | |
| 533 // baud rate is controlled. | |
| 534 | |
| 535 cyg_uint8 baud_divisor = select_baud_2[new_config->baud].timer2_val; | |
|
30
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
536 |
| 2 | 537 if (baud_divisor == 0) |
| 538 return false; // Invalid baud rate selected | |
| 539 | |
| 540 HAL_WRITE_UINT8(mn10300_chan->timer_base+TIMER_BR, baud_divisor); | |
| 541 | |
| 542 HAL_WRITE_UINT8(mn10300_chan->timer_base+TIMER_MD, 0x80 ); | |
| 543 | |
| 544 baud_divisor = select_baud_2[new_config->baud].serial2_val; | |
| 545 | |
| 546 HAL_WRITE_UINT8(mn10300_chan->base+SERIAL_TIM, baud_divisor); | |
| 547 | |
|
30
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
548 cr |= mn10300_chan->timer_select; |
| 2 | 549 } |
| 550 else | |
| 551 { | |
|
30
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
552 cyg_uint16 baud_divisor = select_baud_01[new_config->baud]; |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
553 cyg_uint8 timer_mode = 0x80; |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
554 |
| 2 | 555 if (baud_divisor == 0) |
| 556 return false; // Invalid baud rate selected | |
| 557 | |
|
30
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
558 |
| 2 | 559 HAL_WRITE_UINT8(mn10300_chan->timer_base+TIMER_BR, baud_divisor); |
| 560 | |
|
30
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
561 HAL_WRITE_UINT8(mn10300_chan->timer_base+TIMER_MD, timer_mode ); |
| 2 | 562 |
|
30
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
563 cr |= mn10300_chan->timer_select; |
| 2 | 564 } |
| 565 | |
|
30
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
566 #ifdef PORT3_MD |
| 2 | 567 HAL_WRITE_UINT8( PORT3_MD, 0x01 ); |
|
30
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
568 #endif |
| 2 | 569 |
| 570 // set up other config values: | |
| 571 | |
| 572 cr |= select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5]; | |
| 573 cr |= select_stop_bits[new_config->stop]; | |
| 574 cr |= select_parity[new_config->parity]; | |
| 575 | |
|
30
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
576 cr |= LCR_RXE | LCR_TXE; // enable Rx and Tx |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
577 |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
578 #ifdef CYG_HAL_MN10300_AM31 |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
579 if( mn10300_chan->is_serial2 ) |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
580 { |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
581 // AM31 has an extra TX interrupt enable bit for serial 2. |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
582 DISABLE_TRANSMIT_INTERRUPT(mn10300_chan); |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
583 } |
|
30
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
584 #endif |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
585 |
| 2 | 586 // Write CR into hardware |
| 587 HAL_WRITE_UINT16(mn10300_chan->base+SERIAL_CTR, cr); | |
| 588 | |
|
30
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
589 sr = mn10300_read_sr(mn10300_chan); |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
590 |
| 2 | 591 if (new_config != &chan->config) { |
| 592 chan->config = *new_config; | |
| 593 } | |
| 594 return true; | |
| 595 } | |
| 596 | |
| 597 //------------------------------------------------------------------------- | |
| 598 // Function to initialize the device. Called at bootstrap time. | |
| 599 | |
| 600 bool mn10300_serial_init(struct cyg_devtab_entry *tab) | |
| 601 { | |
| 602 serial_channel *chan = (serial_channel *)tab->priv; | |
| 603 mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; | |
| 604 | |
| 605 (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices | |
| 606 | |
| 607 #ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE | |
| 608 if (chan->out_cbuf.len != 0) { | |
| 609 // Install and enable the receive interrupt | |
| 610 cyg_drv_interrupt_create(mn10300_chan->rx_int, | |
| 611 4, // Priority - what goes here? | |
| 612 (cyg_addrword_t)chan, // Data item passed to interrupt handler | |
| 613 mn10300_serial_rx_ISR, | |
| 614 mn10300_serial_rx_DSR, | |
| 615 &mn10300_chan->rx_interrupt_handle, | |
| 616 &mn10300_chan->rx_interrupt); | |
| 617 cyg_drv_interrupt_attach(mn10300_chan->rx_interrupt_handle); | |
| 618 cyg_drv_interrupt_unmask(mn10300_chan->rx_int); | |
| 619 | |
| 620 // Install and enable the transmit interrupt | |
| 621 cyg_drv_interrupt_create(mn10300_chan->tx_int, | |
| 622 4, // Priority - what goes here? | |
| 623 (cyg_addrword_t)chan, // Data item passed to interrupt handler | |
| 624 mn10300_serial_tx_ISR, | |
| 625 mn10300_serial_tx_DSR, | |
| 626 &mn10300_chan->tx_interrupt_handle, | |
| 627 &mn10300_chan->tx_interrupt); | |
| 628 cyg_drv_interrupt_attach(mn10300_chan->tx_interrupt_handle); | |
| 629 cyg_drv_interrupt_mask(mn10300_chan->tx_int); | |
| 630 } | |
| 631 #endif | |
| 632 | |
| 633 mn10300_serial_config_port(chan, &chan->config, true); | |
| 634 | |
| 635 return true; | |
| 636 } | |
| 637 | |
| 638 //------------------------------------------------------------------------- | |
| 639 // This routine is called when the device is "looked" up (i.e. attached) | |
| 640 | |
| 641 static Cyg_ErrNo | |
| 642 mn10300_serial_lookup(struct cyg_devtab_entry **tab, | |
| 643 struct cyg_devtab_entry *sub_tab, | |
| 644 const char *name) | |
| 645 { | |
| 646 serial_channel *chan = (serial_channel *)(*tab)->priv; | |
| 647 (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices | |
| 648 return ENOERR; | |
| 649 } | |
| 650 | |
| 651 //------------------------------------------------------------------------- | |
| 652 // Return 'true' if character is sent to device | |
| 653 | |
| 654 bool | |
| 655 mn10300_serial_putc(serial_channel *chan, unsigned char c) | |
| 656 { | |
| 657 mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; | |
| 658 cyg_uint8 sr = mn10300_read_sr( mn10300_chan); | |
| 659 | |
| 660 if( (sr & SR_TBF) == 0 ) | |
| 661 { | |
| 662 HAL_WRITE_UINT8( mn10300_chan->base+SERIAL_TXB, c ); | |
| 663 | |
| 664 return true; | |
| 665 } | |
| 666 else return false; | |
| 667 } | |
| 668 | |
| 669 //------------------------------------------------------------------------- | |
| 670 | |
| 671 unsigned char | |
| 672 mn10300_serial_getc(serial_channel *chan) | |
| 673 { | |
| 674 unsigned char c; | |
| 675 mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; | |
| 676 do | |
| 677 { | |
| 678 cyg_uint8 sr = mn10300_read_sr( mn10300_chan ); | |
| 679 | |
| 680 if( (sr & SR_RBF) != 0 ) | |
| 681 { | |
| 682 HAL_READ_UINT8( mn10300_chan->base+SERIAL_RXB, c ); | |
| 683 | |
| 684 break; | |
| 685 } | |
| 686 | |
| 687 } while(1); | |
| 688 | |
| 689 return c; | |
| 690 } | |
| 691 | |
| 692 //------------------------------------------------------------------------- | |
| 693 | |
| 694 bool | |
| 695 mn10300_serial_set_config(serial_channel *chan, cyg_serial_info_t *config) | |
| 696 { | |
| 697 return mn10300_serial_config_port(chan, config, false); | |
| 698 } | |
| 699 | |
| 700 //------------------------------------------------------------------------- | |
| 701 // Enable the transmitter on the device | |
| 702 | |
| 703 static void | |
| 704 mn10300_serial_start_xmit(serial_channel *chan) | |
| 705 { | |
| 706 #ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE | |
| 707 mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; | |
| 708 cyg_uint16 cr; | |
| 709 | |
| 710 HAL_READ_UINT16( mn10300_chan->base+SERIAL_CTR, cr ); | |
| 711 | |
|
30
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
712 ENABLE_TRANSMIT_INTERRUPT(mn10300_chan); |
| 2 | 713 |
| 714 HAL_WRITE_UINT16( mn10300_chan->base+SERIAL_CTR, cr ); | |
| 715 | |
| 716 cyg_drv_interrupt_unmask(mn10300_chan->tx_int); | |
| 717 | |
| 718 (chan->callbacks->xmt_char)(chan); | |
| 719 #endif | |
| 720 } | |
| 721 | |
| 722 //------------------------------------------------------------------------- | |
| 723 // Disable the transmitter on the device | |
| 724 | |
| 725 static void | |
| 726 mn10300_serial_stop_xmit(serial_channel *chan) | |
| 727 { | |
| 728 #ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE | |
| 729 mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; | |
| 730 cyg_uint16 cr; | |
| 731 cyg_uint16 sr; | |
| 732 | |
| 733 // Wait until the transmitter has actually stopped before turning it off. | |
| 734 | |
| 735 do | |
| 736 { | |
| 737 sr = mn10300_read_sr( mn10300_chan ); | |
| 738 | |
| 739 } while( sr & SR_TXF ); | |
| 740 | |
| 741 HAL_READ_UINT16( mn10300_chan->base+SERIAL_CTR, cr ); | |
| 742 | |
|
30
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
743 DISABLE_TRANSMIT_INTERRUPT(mn10300_chan); |
|
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
744 |
| 2 | 745 HAL_WRITE_UINT16( mn10300_chan->base+SERIAL_CTR, cr ); |
| 746 | |
| 747 cyg_drv_interrupt_mask(mn10300_chan->tx_int); | |
| 748 | |
| 749 #endif | |
| 750 } | |
| 751 | |
| 752 //------------------------------------------------------------------------- | |
| 753 // Serial I/O - low level interrupt handlers (ISR) | |
| 754 | |
| 755 #ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE | |
| 756 | |
|
32
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
757 #ifdef CYG_HAL_MN10300_SERIAL_RX_FIFO |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
758 |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
759 // This version of the RX ISR implements a simple receive FIFO. The |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
760 // MN10300 serial devices do not have hardware FIFOs (as found in |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
761 // 16550s for example), and it can be difficult at times to keep up |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
762 // with higher baud rates without overrunning. This ISR implements a |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
763 // software equivalent of the hardware FIFO, placing recieved |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
764 // characters into the FIFO as soon as they arrive. Whenever the DSR |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
765 // is run, it collects all the pending characters from the FIFO for |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
766 // delivery to the application. Neither the ISR or DSR disable |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
767 // interrupts, instead we rely on being able to write the head and |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
768 // tail pointers atomically, to implement lock-free synchronization. |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
769 |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
770 static cyg_uint32 |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
771 mn10300_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data) |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
772 { |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
773 serial_channel *chan = (serial_channel *)data; |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
774 mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
775 cyg_uint8 sr = mn10300_read_sr( mn10300_chan); |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
776 |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
777 while( (sr & SR_RBF) != 0 ) |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
778 { |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
779 register cyg_int32 head = mn10300_chan->fifo_head; |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
780 cyg_uint8 c; |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
781 int i; |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
782 HAL_READ_UINT8( mn10300_chan->base+SERIAL_RXB, c ); |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
783 |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
784 mn10300_chan->fifo[head++] = c; |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
785 |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
786 if( head >= sizeof(mn10300_chan->fifo) ) |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
787 head = 0; |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
788 |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
789 mn10300_chan->fifo_head = head; |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
790 |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
791 sr = mn10300_read_sr( mn10300_chan); |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
792 |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
793 } |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
794 |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
795 cyg_drv_interrupt_acknowledge(mn10300_chan->rx_int); |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
796 |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
797 return CYG_ISR_CALL_DSR; // Cause DSR to be run |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
798 } |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
799 |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
800 #else |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
801 |
| 2 | 802 static cyg_uint32 |
| 803 mn10300_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data) | |
| 804 { | |
| 805 serial_channel *chan = (serial_channel *)data; | |
| 806 mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; | |
|
30
641b639be825
Merge from eCos master repository on 1999-08-16-22:01:37-BST
jlarmour
parents:
10
diff
changeset
|
807 |
| 2 | 808 cyg_drv_interrupt_mask(mn10300_chan->rx_int); |
| 809 cyg_drv_interrupt_acknowledge(mn10300_chan->rx_int); | |
| 810 | |
| 811 return CYG_ISR_CALL_DSR; // Cause DSR to be run | |
| 812 } | |
| 813 | |
|
32
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
814 #endif |
| 2 | 815 |
| 816 static cyg_uint32 | |
| 817 mn10300_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data) | |
| 818 { | |
| 819 serial_channel *chan = (serial_channel *)data; | |
| 820 mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; | |
| 821 | |
| 822 cyg_drv_interrupt_mask(mn10300_chan->tx_int); | |
| 823 cyg_drv_interrupt_acknowledge(mn10300_chan->tx_int); | |
| 824 | |
| 825 return CYG_ISR_CALL_DSR; // Cause DSR to be run | |
| 826 } | |
| 827 | |
| 828 #endif | |
| 829 | |
| 830 //------------------------------------------------------------------------- | |
| 831 // Serial I/O - high level interrupt handler (DSR) | |
| 832 | |
| 833 #ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE | |
| 834 | |
|
32
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
835 #ifdef CYG_HAL_MN10300_SERIAL_RX_FIFO |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
836 |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
837 static void |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
838 mn10300_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
839 { |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
840 serial_channel *chan = (serial_channel *)data; |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
841 mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
842 register cyg_int32 head = mn10300_chan->fifo_head; |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
843 register cyg_int32 tail = mn10300_chan->fifo_tail; |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
844 |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
845 while( head != tail ) |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
846 { |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
847 cyg_uint8 c = mn10300_chan->fifo[tail++]; |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
848 |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
849 if( tail >= sizeof(mn10300_chan->fifo) ) tail = 0; |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
850 |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
851 (chan->callbacks->rcv_char)(chan, c); |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
852 } |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
853 |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
854 mn10300_chan->fifo_tail = tail; |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
855 } |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
856 |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
857 #else |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
858 |
| 2 | 859 static void |
| 860 mn10300_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) | |
| 861 { | |
| 862 serial_channel *chan = (serial_channel *)data; | |
| 863 mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; | |
| 864 cyg_uint8 sr = mn10300_read_sr( mn10300_chan); | |
| 865 | |
| 866 if( (sr & SR_RBF) != 0 ) | |
| 867 { | |
| 868 cyg_uint8 rxb; | |
| 869 HAL_READ_UINT8( mn10300_chan->base+SERIAL_RXB, rxb ); | |
| 870 | |
| 871 (chan->callbacks->rcv_char)(chan, rxb); | |
| 872 } | |
| 873 | |
| 874 cyg_drv_interrupt_unmask(mn10300_chan->rx_int); | |
| 875 } | |
| 876 | |
|
32
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
877 #endif |
|
5af43b635655
Merge from eCos master repository on 1999-08-18-15:20:01-BST
jlarmour
parents:
30
diff
changeset
|
878 |
| 2 | 879 static void |
| 880 mn10300_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) | |
| 881 { | |
| 882 serial_channel *chan = (serial_channel *)data; | |
| 883 mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; | |
| 884 cyg_uint8 sr = mn10300_read_sr( mn10300_chan); | |
| 885 | |
| 886 if( (sr & SR_TBF) == 0 ) | |
| 887 { | |
| 888 (chan->callbacks->xmt_char)(chan); | |
| 889 } | |
| 890 | |
| 891 cyg_drv_interrupt_unmask(mn10300_chan->tx_int); | |
| 892 } | |
| 893 | |
| 894 #endif | |
| 895 | |
| 896 #endif // CYGPKG_IO_SERIAL_MN10300 | |
| 897 | |
| 898 //------------------------------------------------------------------------- | |
| 899 // EOF mn10300.c |
