1 //==========================================================================
5 // Serial device driver for mn10300 on-chip serial devices
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
41 //#####DESCRIPTIONBEGIN####
44 // Contributors: nickg
46 // Purpose: MN10300 serial device driver
47 // Description: MN10300 serial device driver
49 //####DESCRIPTIONEND####
51 //==========================================================================
53 #include <pkgconf/hal.h>
54 #include <pkgconf/io_serial.h>
55 #include <cyg/hal/hal_io.h>
57 #include <cyg/io/io.h>
58 #include <cyg/io/devtab.h>
59 #include <cyg/io/serial.h>
60 #include <cyg/hal/hal_intr.h>
62 #ifdef CYGPKG_IO_SERIAL_MN10300
64 #define CYG_HAL_MN10300_SERIAL_RX_FIFO
66 //-------------------------------------------------------------------------
68 extern void diag_printf(const char *fmt, ...);
70 //-------------------------------------------------------------------------
71 // Forward definitions
73 static bool mn10300_serial_init(struct cyg_devtab_entry *tab);
74 static bool mn10300_serial_putc(serial_channel *chan, unsigned char c);
75 static Cyg_ErrNo mn10300_serial_lookup(struct cyg_devtab_entry **tab,
76 struct cyg_devtab_entry *sub_tab,
78 static unsigned char mn10300_serial_getc(serial_channel *chan);
79 static Cyg_ErrNo mn10300_serial_set_config(serial_channel *chan, cyg_uint32 key,
80 const void *xbuf, cyg_uint32 *len);
81 static void mn10300_serial_start_xmit(serial_channel *chan);
82 static void mn10300_serial_stop_xmit(serial_channel *chan);
84 #ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE
85 static cyg_uint32 mn10300_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data);
86 static cyg_uint32 mn10300_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data);
87 static void mn10300_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
88 static void mn10300_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
91 //-------------------------------------------------------------------------
95 //-------------------------------------------------------------------------
96 // MN10300 serial line control register values:
98 // Offsets to serial control registers from base
99 #define SERIAL_CTR 0x0
100 #define SERIAL_ICR 0x4
101 #define SERIAL_TXB 0x8
102 #define SERIAL_RXB 0x9
103 #define SERIAL_STR 0xc
104 #define SERIAL_TIM 0xd
106 // Status register bits
112 // Control register bits
114 #define LCR_SB1_5 0x00
116 #define LCR_PN 0x00 // Parity mode - none
117 #define LCR_PS 0x40 // Forced "space" parity
118 #define LCR_PM 0x50 // Forced "mark" parity
119 #define LCR_PE 0x60 // Parity mode - even
120 #define LCR_PO 0x70 // Parity mode - odd
121 #define LCR_WL5 0x00 // not supported - use 7bit
122 #define LCR_WL6 0x00 // not supported - use 7bit
123 #define LCR_WL7 0x00 // 7 bit chars
124 #define LCR_WL8 0x80 // 8 bit chars
125 #define LCR_RXE 0x4000 // receive enable
126 #define LCR_TXE 0x8000 // transmit enable
128 #if defined(CYGPKG_HAL_MN10300_AM31)
129 #define LCR_TWE 0x0100 // interrupt enable (only on serial2/AM31)
131 #define LCR_TWE 0x0000 // Bit does not exist in other variants
134 //-------------------------------------------------------------------------
135 // MN10300 timer registers:
139 #define TIMER_MD 0x00
140 #define TIMER_BR 0x10
142 //-------------------------------------------------------------------------
143 // Serial and timer base registers:
145 #if defined(CYGPKG_HAL_MN10300_AM31)
147 #define SERIAL0_BASE 0x34000800
148 #define SERIAL1_BASE 0x34000810
149 #define SERIAL2_BASE 0x34000820
151 #define TIMER0_BASE 0x34001000
152 #define TIMER1_BASE 0x34001001
153 #define TIMER2_BASE 0x34001002
155 #define SERIAL0_TIMER_SELECT 0x0004 // timer 0
156 #define SERIAL1_TIMER_SELECT 0x0004 // timer 1
157 #define SERIAL2_TIMER_SELECT 0x0001 // timer 2
159 #ifdef CYGPKG_HAL_MN10300_AM31_STDEVAL1
160 // The use of PORT3 to provide CTS/CTR is specific to
161 // the STDEVAL1 board only.
162 #define PORT3_MD 0x36008025
165 #define ENABLE_TRANSMIT_INTERRUPT(mn10300_chan) \
167 if( mn10300_chan->is_serial2 ) \
173 #define DISABLE_TRANSMIT_INTERRUPT(mn10300_chan) \
175 if( mn10300_chan->is_serial2 ) \
181 #elif defined(CYGPKG_HAL_MN10300_AM33)
183 #define SERIAL0_BASE 0xd4002000
184 #define SERIAL1_BASE 0xd4002010
185 #define SERIAL2_BASE 0xd4002020
187 #define TIMER0_BASE 0xd4003002
188 #define TIMER1_BASE 0xd4003001
189 #define TIMER2_BASE 0xd4003003
191 #define SERIAL0_TIMER_SELECT 0x0005 // timer 2
192 #define SERIAL1_TIMER_SELECT 0x0004 // timer 1
193 #define SERIAL2_TIMER_SELECT 0x0003 // timer 3
195 #define HW_TIMER0 0xd4003000
197 #define ENABLE_TRANSMIT_INTERRUPT(mn10300_chan)
199 #define DISABLE_TRANSMIT_INTERRUPT(mn10300_chan)
203 #error Unsupported MN10300 variant
207 //-------------------------------------------------------------------------
208 // Tables to map input values to hardware settings
210 static unsigned char select_word_length[] = {
211 LCR_WL5, // 5 bits / word (char)
217 static unsigned char select_stop_bits[] = {
219 LCR_SB1, // 1 stop bit
220 LCR_SB1_5, // 1.5 stop bit
221 LCR_SB2 // 2 stop bits
224 static unsigned char select_parity[] = {
226 LCR_PE, // Even parity
227 LCR_PO, // Odd parity
228 LCR_PM, // Mark parity
229 LCR_PS, // Space parity
232 #if defined(CYGPKG_HAL_MN10300_AM31)
234 static unsigned short select_baud_01[] = {
259 // Serial 2 has its own timer register in addition to using timer 2 to
260 // supply the baud rate generator. Both of these must be proframmed to
261 // get the right baud rate. The following values come from Matsushita
262 // with some modifications from Cygmon.
265 cyg_uint8 serial2_val;
266 cyg_uint8 timer2_val;
267 } select_baud_2[] = {
292 #elif defined(CYGPKG_HAL_MN10300_AM33)
294 // The AM33 runs at a different clock rate and therefore has a
295 // different set of dividers for the baud rate.
297 static unsigned short select_baud_01[] = {
322 // Serial 2 has its own timer register in addition to using timer 2 to
323 // supply the baud rate generator. Both of these must be proframmed to
324 // get the right baud rate. The following values come from Matsushita
325 // with some modifications from Cygmon.
327 // The values in the following table differ significantly from those
328 // given in the Matsushita documentation. These have been determined
329 // by (somewhat exhaustive) experiment, the values in the documentation
330 // do not appear to work at all.
334 cyg_uint8 serial2_val;
335 cyg_uint8 timer2_val;
336 } select_baud_2[] = {
363 #error Unsupported MN10300 variant
367 //-------------------------------------------------------------------------
368 // Info for each serial device controlled
370 typedef struct mn10300_serial_info {
372 CYG_ADDRWORD timer_base;
373 CYG_WORD timer_select;
377 cyg_interrupt rx_interrupt;
378 cyg_interrupt tx_interrupt;
379 cyg_handle_t rx_interrupt_handle;
380 cyg_handle_t tx_interrupt_handle;
381 #ifdef CYG_HAL_MN10300_SERIAL_RX_FIFO
382 volatile cyg_int32 fifo_head;
383 volatile cyg_int32 fifo_tail;
384 volatile cyg_uint8 fifo[16];
386 } mn10300_serial_info;
388 //-------------------------------------------------------------------------
389 // Callback functions exported by this driver
391 static SERIAL_FUNS(mn10300_serial_funs,
394 mn10300_serial_set_config,
395 mn10300_serial_start_xmit,
396 mn10300_serial_stop_xmit
399 //-------------------------------------------------------------------------
400 // Hardware info for each serial line
402 #ifndef CYGPKG_HAL_MN10300_AM31_STDEVAL1
403 #ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL0
404 static mn10300_serial_info mn10300_serial_info0 = {
407 SERIAL0_TIMER_SELECT,
408 CYGNUM_HAL_INTERRUPT_SERIAL_0_RX,
409 CYGNUM_HAL_INTERRUPT_SERIAL_0_TX,
412 #if CYGNUM_IO_SERIAL_MN10300_SERIAL0_BUFSIZE > 0
413 static unsigned char mn10300_serial_out_buf0[CYGNUM_IO_SERIAL_MN10300_SERIAL0_BUFSIZE];
414 static unsigned char mn10300_serial_in_buf0[CYGNUM_IO_SERIAL_MN10300_SERIAL0_BUFSIZE];
416 #endif // CYGPKG_IO_SERIAL_MN10300_SERIAL0
419 #ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL1
420 static mn10300_serial_info mn10300_serial_info1 = {
423 SERIAL1_TIMER_SELECT,
424 CYGNUM_HAL_INTERRUPT_SERIAL_1_RX,
425 CYGNUM_HAL_INTERRUPT_SERIAL_1_TX,
428 #if CYGNUM_IO_SERIAL_MN10300_SERIAL1_BUFSIZE > 0
429 static unsigned char mn10300_serial_out_buf1[CYGNUM_IO_SERIAL_MN10300_SERIAL1_BUFSIZE];
430 static unsigned char mn10300_serial_in_buf1[CYGNUM_IO_SERIAL_MN10300_SERIAL1_BUFSIZE];
432 #endif // CYGPKG_IO_SERIAL_MN10300_SERIAL1
434 #ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL2
435 static mn10300_serial_info mn10300_serial_info2 = {
438 SERIAL2_TIMER_SELECT,
439 CYGNUM_HAL_INTERRUPT_SERIAL_2_RX,
440 CYGNUM_HAL_INTERRUPT_SERIAL_2_TX,
443 #if CYGNUM_IO_SERIAL_MN10300_SERIAL2_BUFSIZE > 0
444 static unsigned char mn10300_serial_out_buf2[CYGNUM_IO_SERIAL_MN10300_SERIAL2_BUFSIZE];
445 static unsigned char mn10300_serial_in_buf2[CYGNUM_IO_SERIAL_MN10300_SERIAL2_BUFSIZE];
447 #endif // CYGPKG_IO_SERIAL_MN10300_SERIAL2
450 //-------------------------------------------------------------------------
451 // Channel descriptions:
453 #ifdef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE
454 #define SIZEOF_BUF(_x_) 0
456 #define SIZEOF_BUF(_x_) sizeof(_x_)
459 #ifndef CYGPKG_HAL_MN10300_AM31_STDEVAL1
460 #ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL0
461 #if CYGNUM_IO_SERIAL_MN10300_SERIAL0_BUFSIZE > 0
462 static SERIAL_CHANNEL_USING_INTERRUPTS(mn10300_serial_channel0,
464 mn10300_serial_info0,
465 CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MN10300_SERIAL0_BAUD),
466 CYG_SERIAL_STOP_DEFAULT,
467 CYG_SERIAL_PARITY_DEFAULT,
468 CYG_SERIAL_WORD_LENGTH_DEFAULT,
469 CYG_SERIAL_FLAGS_DEFAULT,
470 &mn10300_serial_out_buf0[0],
471 SIZEOF_BUF(mn10300_serial_out_buf0),
472 &mn10300_serial_in_buf0[0],
473 SIZEOF_BUF(mn10300_serial_in_buf0)
476 static SERIAL_CHANNEL(mn10300_serial_channel0,
478 mn10300_serial_info0,
479 CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MN10300_SERIAL0_BAUD),
480 CYG_SERIAL_STOP_DEFAULT,
481 CYG_SERIAL_PARITY_DEFAULT,
482 CYG_SERIAL_WORD_LENGTH_DEFAULT,
483 CYG_SERIAL_FLAGS_DEFAULT
486 #endif // CYGPKG_IO_SERIAL_MN10300_SERIAL0
489 #ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL1
490 #if CYGNUM_IO_SERIAL_MN10300_SERIAL1_BUFSIZE > 0
491 static SERIAL_CHANNEL_USING_INTERRUPTS(mn10300_serial_channel1,
493 mn10300_serial_info1,
494 CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MN10300_SERIAL1_BAUD),
495 CYG_SERIAL_STOP_DEFAULT,
496 CYG_SERIAL_PARITY_DEFAULT,
497 CYG_SERIAL_WORD_LENGTH_DEFAULT,
498 CYG_SERIAL_FLAGS_DEFAULT,
499 &mn10300_serial_out_buf1[0],
500 SIZEOF_BUF(mn10300_serial_out_buf1),
501 &mn10300_serial_in_buf1[0],
502 SIZEOF_BUF(mn10300_serial_in_buf1)
505 static SERIAL_CHANNEL(mn10300_serial_channel1,
507 mn10300_serial_info1,
508 CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MN10300_SERIAL1_BAUD),
509 CYG_SERIAL_STOP_DEFAULT,
510 CYG_SERIAL_PARITY_DEFAULT,
511 CYG_SERIAL_WORD_LENGTH_DEFAULT,
512 CYG_SERIAL_FLAGS_DEFAULT
515 #endif // CYGPKG_IO_SERIAL_MN10300_SERIAL1
517 #ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL2
518 #if CYGNUM_IO_SERIAL_MN10300_SERIAL2_BUFSIZE > 0
519 static SERIAL_CHANNEL_USING_INTERRUPTS(mn10300_serial_channel2,
521 mn10300_serial_info2,
522 CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MN10300_SERIAL2_BAUD),
523 CYG_SERIAL_STOP_DEFAULT,
524 CYG_SERIAL_PARITY_DEFAULT,
525 CYG_SERIAL_WORD_LENGTH_DEFAULT,
526 CYG_SERIAL_FLAGS_DEFAULT,
527 &mn10300_serial_out_buf2[0],
528 SIZEOF_BUF(mn10300_serial_out_buf2),
529 &mn10300_serial_in_buf2[0],
530 SIZEOF_BUF(mn10300_serial_in_buf2)
533 static SERIAL_CHANNEL(mn10300_serial_channel2,
535 mn10300_serial_info2,
536 CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MN10300_SERIAL2_BAUD),
537 CYG_SERIAL_STOP_DEFAULT,
538 CYG_SERIAL_PARITY_DEFAULT,
539 CYG_SERIAL_WORD_LENGTH_DEFAULT,
540 CYG_SERIAL_FLAGS_DEFAULT
543 #endif // CYGPKG_IO_SERIAL_MN10300_SERIAL2
545 //-------------------------------------------------------------------------
546 // And finally, the device table entries:
548 #ifndef CYGPKG_HAL_MN10300_AM31_STDEVAL1
549 #ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL0
550 // On the standard eval board serial0 is not connected. If enabled, it
551 // generates continuous frame error and overrun interrupts. Hence we do
553 DEVTAB_ENTRY(mn10300_serial_io0,
554 CYGDAT_IO_SERIAL_MN10300_SERIAL0_NAME,
555 0, // Does not depend on a lower level interface
556 &cyg_io_serial_devio,
558 mn10300_serial_lookup, // Serial driver may need initializing
559 &mn10300_serial_channel0
561 #endif // CYGPKG_IO_SERIAL_MN10300_SERIAL0
564 #ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL1
565 DEVTAB_ENTRY(mn10300_serial_io1,
566 CYGDAT_IO_SERIAL_MN10300_SERIAL1_NAME,
567 0, // Does not depend on a lower level interface
568 &cyg_io_serial_devio,
570 mn10300_serial_lookup, // Serial driver may need initializing
571 &mn10300_serial_channel1
573 #endif // CYGPKG_IO_SERIAL_MN10300_SERIAL1
575 #ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL2
576 DEVTAB_ENTRY(mn10300_serial_io2,
577 CYGDAT_IO_SERIAL_MN10300_SERIAL2_NAME,
578 0, // Does not depend on a lower level interface
579 &cyg_io_serial_devio,
581 mn10300_serial_lookup, // Serial driver may need initializing
582 &mn10300_serial_channel2
584 #endif // CYGPKG_IO_SERIAL_MN10300_SERIAL2
586 //-------------------------------------------------------------------------
587 // Read the serial line's status register. Serial 2 has an 8 bit status
588 // register while serials 0 and 1 have 16 bit registers. This function
589 // uses the correct size access, but passes back a 16 bit quantity for
592 static cyg_uint16 mn10300_read_sr( mn10300_serial_info *mn10300_chan )
595 if( mn10300_chan->is_serial2 )
598 HAL_READ_UINT8(mn10300_chan->base+SERIAL_STR, sr8);
603 HAL_READ_UINT16(mn10300_chan->base+SERIAL_STR, sr);
609 //-------------------------------------------------------------------------
612 mn10300_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init)
614 mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;
618 // wait for the device to become quiescent. This could take some time
619 // if the device had been transmitting at a low baud rate.
621 sr = mn10300_read_sr(mn10300_chan);
622 } while (sr & (SR_RXF|SR_TXF));
624 // Disable device entirely.
625 HAL_WRITE_UINT16(mn10300_chan->base+SERIAL_CTR, 0);
627 // Set up the Interrupt Mode Register
628 HAL_WRITE_UINT8(mn10300_chan->base+SERIAL_ICR, 0);
631 if( mn10300_chan->is_serial2 )
633 // Serial 2 is a bit different from 0 and 1 in the way that the
634 // baud rate is controlled.
636 cyg_uint8 baud_divisor = select_baud_2[new_config->baud].timer2_val;
638 if (baud_divisor == 0)
639 return false; // Invalid baud rate selected
641 HAL_WRITE_UINT8(mn10300_chan->timer_base+TIMER_BR, baud_divisor);
643 HAL_WRITE_UINT8(mn10300_chan->timer_base+TIMER_MD, 0x80 );
645 baud_divisor = select_baud_2[new_config->baud].serial2_val;
647 HAL_WRITE_UINT8(mn10300_chan->base+SERIAL_TIM, baud_divisor);
649 cr |= mn10300_chan->timer_select;
653 cyg_uint16 baud_divisor = select_baud_01[new_config->baud];
654 cyg_uint8 timer_mode = 0x80;
656 if (baud_divisor == 0)
657 return false; // Invalid baud rate selected
659 #if defined(CYGPKG_HAL_MN10300_AM33)
660 if( baud_divisor > 255 )
662 // The AM33 runs at a higher clock rate than the AM31 and
663 // needs a bigger divisor for low baud rates. We do this by
664 // using timer 0 as a prescaler. We set it to 198 so we can then
665 // use it to prescale for both serial0 and serial1 if they need
667 static int timer0_initialized = 0;
671 if( !timer0_initialized )
673 timer0_initialized = 1;
674 HAL_WRITE_UINT8(HW_TIMER0+TIMER_BR, 198 );
675 HAL_WRITE_UINT8(HW_TIMER0+TIMER_MD, 0x80 );
680 HAL_WRITE_UINT8(mn10300_chan->timer_base+TIMER_BR, baud_divisor);
682 HAL_WRITE_UINT8(mn10300_chan->timer_base+TIMER_MD, timer_mode );
684 cr |= mn10300_chan->timer_select;
688 HAL_WRITE_UINT8( PORT3_MD, 0x01 );
691 // set up other config values:
693 cr |= select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5];
694 cr |= select_stop_bits[new_config->stop];
695 cr |= select_parity[new_config->parity];
697 cr |= LCR_RXE | LCR_TXE; // enable Rx and Tx
699 #ifdef CYGPKG_HAL_MN10300_AM31
700 if( mn10300_chan->is_serial2 )
702 // AM31 has an extra TX interrupt enable bit for serial 2.
703 DISABLE_TRANSMIT_INTERRUPT(mn10300_chan);
707 // Write CR into hardware
708 HAL_WRITE_UINT16(mn10300_chan->base+SERIAL_CTR, cr);
710 sr = mn10300_read_sr(mn10300_chan);
712 if (new_config != &chan->config) {
713 chan->config = *new_config;
718 //-------------------------------------------------------------------------
719 // Function to initialize the device. Called at bootstrap time.
721 bool mn10300_serial_init(struct cyg_devtab_entry *tab)
723 serial_channel *chan = (serial_channel *)tab->priv;
724 mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;
726 (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
728 #ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE
729 if (chan->out_cbuf.len != 0) {
730 // Install and enable the receive interrupt
731 cyg_drv_interrupt_create(mn10300_chan->rx_int,
732 4, // Priority - what goes here?
733 (cyg_addrword_t)chan, // Data item passed to interrupt handler
734 mn10300_serial_rx_ISR,
735 mn10300_serial_rx_DSR,
736 &mn10300_chan->rx_interrupt_handle,
737 &mn10300_chan->rx_interrupt);
738 cyg_drv_interrupt_attach(mn10300_chan->rx_interrupt_handle);
739 cyg_drv_interrupt_unmask(mn10300_chan->rx_int);
741 // Install and enable the transmit interrupt
742 cyg_drv_interrupt_create(mn10300_chan->tx_int,
743 4, // Priority - what goes here?
744 (cyg_addrword_t)chan, // Data item passed to interrupt handler
745 mn10300_serial_tx_ISR,
746 mn10300_serial_tx_DSR,
747 &mn10300_chan->tx_interrupt_handle,
748 &mn10300_chan->tx_interrupt);
749 cyg_drv_interrupt_attach(mn10300_chan->tx_interrupt_handle);
750 cyg_drv_interrupt_mask(mn10300_chan->tx_int);
754 mn10300_serial_config_port(chan, &chan->config, true);
759 //-------------------------------------------------------------------------
760 // This routine is called when the device is "looked" up (i.e. attached)
763 mn10300_serial_lookup(struct cyg_devtab_entry **tab,
764 struct cyg_devtab_entry *sub_tab,
767 serial_channel *chan = (serial_channel *)(*tab)->priv;
768 (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
772 //-------------------------------------------------------------------------
773 // Return 'true' if character is sent to device
776 mn10300_serial_putc(serial_channel *chan, unsigned char c)
778 mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;
779 cyg_uint8 sr = mn10300_read_sr( mn10300_chan);
781 if( (sr & SR_TBF) == 0 )
783 HAL_WRITE_UINT8( mn10300_chan->base+SERIAL_TXB, c );
790 //-------------------------------------------------------------------------
793 mn10300_serial_getc(serial_channel *chan)
796 mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;
799 cyg_uint8 sr = mn10300_read_sr( mn10300_chan );
801 if( (sr & SR_RBF) != 0 )
803 HAL_READ_UINT8( mn10300_chan->base+SERIAL_RXB, c );
813 //-------------------------------------------------------------------------
816 mn10300_serial_set_config(serial_channel *chan, cyg_uint32 key,
817 const void *xbuf, cyg_uint32 *len)
820 case CYG_IO_SET_CONFIG_SERIAL_INFO:
822 cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
823 if ( *len < sizeof(cyg_serial_info_t) ) {
826 *len = sizeof(cyg_serial_info_t);
827 if ( true != mn10300_serial_config_port(chan, config, false) )
837 //-------------------------------------------------------------------------
838 // Enable the transmitter on the device
841 mn10300_serial_start_xmit(serial_channel *chan)
843 #ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE
844 mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;
847 HAL_READ_UINT16( mn10300_chan->base+SERIAL_CTR, cr );
849 ENABLE_TRANSMIT_INTERRUPT(mn10300_chan);
851 HAL_WRITE_UINT16( mn10300_chan->base+SERIAL_CTR, cr );
853 cyg_drv_interrupt_unmask(mn10300_chan->tx_int);
855 (chan->callbacks->xmt_char)(chan);
859 //-------------------------------------------------------------------------
860 // Disable the transmitter on the device
863 mn10300_serial_stop_xmit(serial_channel *chan)
865 #ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE
866 mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;
870 // Wait until the transmitter has actually stopped before turning it off.
874 sr = mn10300_read_sr( mn10300_chan );
876 } while( sr & SR_TXF );
878 HAL_READ_UINT16( mn10300_chan->base+SERIAL_CTR, cr );
880 DISABLE_TRANSMIT_INTERRUPT(mn10300_chan);
882 HAL_WRITE_UINT16( mn10300_chan->base+SERIAL_CTR, cr );
884 cyg_drv_interrupt_mask(mn10300_chan->tx_int);
889 //-------------------------------------------------------------------------
890 // Serial I/O - low level interrupt handlers (ISR)
892 #ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE
894 #ifdef CYG_HAL_MN10300_SERIAL_RX_FIFO
896 // This version of the RX ISR implements a simple receive FIFO. The
897 // MN10300 serial devices do not have hardware FIFOs (as found in
898 // 16550s for example), and it can be difficult at times to keep up
899 // with higher baud rates without overrunning. This ISR implements a
900 // software equivalent of the hardware FIFO, placing recieved
901 // characters into the FIFO as soon as they arrive. Whenever the DSR
902 // is run, it collects all the pending characters from the FIFO for
903 // delivery to the application. Neither the ISR or DSR disable
904 // interrupts, instead we rely on being able to write the head and
905 // tail pointers atomically, to implement lock-free synchronization.
908 mn10300_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data)
910 serial_channel *chan = (serial_channel *)data;
911 mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;
912 cyg_uint8 sr = mn10300_read_sr( mn10300_chan);
914 while( (sr & SR_RBF) != 0 )
916 register cyg_int32 head = mn10300_chan->fifo_head;
919 HAL_READ_UINT8( mn10300_chan->base+SERIAL_RXB, c );
921 mn10300_chan->fifo[head++] = c;
923 if( head >= sizeof(mn10300_chan->fifo) )
926 mn10300_chan->fifo_head = head;
928 sr = mn10300_read_sr( mn10300_chan);
932 cyg_drv_interrupt_acknowledge(mn10300_chan->rx_int);
934 return CYG_ISR_CALL_DSR; // Cause DSR to be run
940 mn10300_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data)
942 serial_channel *chan = (serial_channel *)data;
943 mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;
945 cyg_drv_interrupt_mask(mn10300_chan->rx_int);
946 cyg_drv_interrupt_acknowledge(mn10300_chan->rx_int);
948 return CYG_ISR_CALL_DSR; // Cause DSR to be run
954 mn10300_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data)
956 serial_channel *chan = (serial_channel *)data;
957 mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;
959 cyg_drv_interrupt_mask(mn10300_chan->tx_int);
960 cyg_drv_interrupt_acknowledge(mn10300_chan->tx_int);
962 return CYG_ISR_CALL_DSR; // Cause DSR to be run
967 //-------------------------------------------------------------------------
968 // Serial I/O - high level interrupt handler (DSR)
970 #ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE
972 #ifdef CYG_HAL_MN10300_SERIAL_RX_FIFO
975 mn10300_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
977 serial_channel *chan = (serial_channel *)data;
978 mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;
979 register cyg_int32 head = mn10300_chan->fifo_head;
980 register cyg_int32 tail = mn10300_chan->fifo_tail;
982 while( head != tail )
984 cyg_uint8 c = mn10300_chan->fifo[tail++];
986 if( tail >= sizeof(mn10300_chan->fifo) ) tail = 0;
988 (chan->callbacks->rcv_char)(chan, c);
991 mn10300_chan->fifo_tail = tail;
997 mn10300_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
999 serial_channel *chan = (serial_channel *)data;
1000 mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;
1001 cyg_uint8 sr = mn10300_read_sr( mn10300_chan);
1003 if( (sr & SR_RBF) != 0 )
1006 HAL_READ_UINT8( mn10300_chan->base+SERIAL_RXB, rxb );
1008 (chan->callbacks->rcv_char)(chan, rxb);
1011 cyg_drv_interrupt_unmask(mn10300_chan->rx_int);
1017 mn10300_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
1019 serial_channel *chan = (serial_channel *)data;
1020 mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;
1021 cyg_uint8 sr = mn10300_read_sr( mn10300_chan);
1023 if( (sr & SR_TBF) == 0 )
1025 (chan->callbacks->xmt_char)(chan);
1028 cyg_drv_interrupt_unmask(mn10300_chan->tx_int);
1033 #endif // CYGPKG_IO_SERIAL_MN10300
1035 //-------------------------------------------------------------------------