source: rtems/c/src/lib/libbsp/m68k/idp/console/duart.c @ 8f35817

4.104.114.84.95
Last change on this file since 8f35817 was d074e12, checked in by Joel Sherrill <joel.sherrill@…>, on 08/04/97 at 22:22:59

Switched to new version of mc68681.h

  • Property mode set to 100644
File size: 8.2 KB
Line 
1/*
2 *  $Id$
3 */
4
5/*#########################################################
6#
7# This code is a modified version of what you will find at the
8# end of the IDP User's manual.  The original code is copyrighted
9# by Motorola and Motorola Semiconductor Products as well as
10# Motorola Software products group.
11#
12# Modifications to the original IDP code by Doug McBride, Colorado
13# Space Grant College.  Modifications include a means of accessing
14# port B of the duart as well as port A as well as modifications for
15# buffering and RTEMS support.  Modifications are provided
16# as is and may not be correct.
17#
18# Rob Savoye provided the format for the mc68681 header file
19#
20# Joel Sherrill provided inspiration for recoding my original assembly
21# for this file into C (a good idea)
22#
23##########################################################*/
24
25#include <bsp.h>
26#include <ringbuf.h>
27
28rtems_isr C_Receive_ISR(rtems_vector_number vector);
29extern Ring_buffer_t  Buffer[];
30
31extern unsigned char inbuf[];
32extern unsigned char inbuf_portb[];
33extern unsigned tail;
34extern unsigned tail_portb;
35unsigned char Pit_initialized = 0;
36
37/*#####################################################################
38# The volatile routine to initialize the duart -- port a and port b
39######################################################################*/
40volatile void init_pit()
41{
42  /*
43   *  ports A & B while configuring PIT by:
44   *
45   *    + disable Interrupt Mask Register
46   *    + disable port A transmitter
47   *    + disable port A receiver
48   *    + disable port B transmitter
49   *    + disable port B receiver
50   */
51
52  MC68681_WRITE(DUART_ADDR, MC68681_INTERRUPT_MASK_REG, 0x00);
53  MC68681_WRITE(DUART_ADDR, MC68681_COMMAND_REG_A ,MC68681_MODE_REG_DISABLE_TX);
54  MC68681_WRITE(DUART_ADDR, MC68681_COMMAND_REG_A, MC68681_MODE_REG_DISABLE_RX);
55  MC68681_WRITE(DUART_ADDR, MC68681_COMMAND_REG_B, MC68681_MODE_REG_DISABLE_TX);
56  MC68681_WRITE(DUART_ADDR, MC68681_COMMAND_REG_B, MC68681_MODE_REG_DISABLE_RX);
57
58  /*
59   *  install ISR for ports A and B
60   */
61  set_vector(C_Receive_ISR, (VECT+H3VECT), 1);
62
63  /*
64   *  initialize pit
65   *
66   *  set mode to 0 -- disable all ports
67   *  set up pirq and piack
68   *  all pins on port b are input
69   *  submode 1x, h3 interrupt enabled
70   *  setup pivr
71   *  turn on all ports
72   */
73  MC68230_WRITE(PGCR, 0x00);
74  MC68230_WRITE(PSRR, 0x18);
75  MC68230_WRITE(PBDDR, 0x00);
76  MC68230_WRITE(PBCR, 0x82);
77  MC68230_WRITE(PIVR, VECT);
78  MC68230_WRITE(PGCR, 0x20);
79
80  /*
81   *  For some reason, the reset of receiver/transmitter only works for
82   *  the first time around -- it garbles the output otherwise
83   *  (e.g., sp21)
84   */
85  if (!Pit_initialized)
86  {
87    /*
88     * initialize the duart registers on port b
89     * WARNING:OPTIMIZER MAY ONLY EXECUTE THIRD STATEMENT IF NOT VOLATILE
90     *
91     *  reset tx, channel b
92     *  reset rx, channel b
93     *  reset mr pointer, ch
94     */
95     MC68681_WRITE(DUART_ADDR, MC68681_COMMAND_REG_B, MC68681_MODE_REG_RESET_TX);
96     MC68681_WRITE(DUART_ADDR, MC68681_COMMAND_REG_B, MC68681_MODE_REG_RESET_RX);
97     MC68681_WRITE(DUART_ADDR, MC68681_COMMAND_REG_B, MC68681_MODE_REG_RESET_MR_PTR);
98
99    /*
100     * initialize the duart registers on port a
101     * WARNING:OPTIMIZER MAY ONLY EXECUTE THIRD STATEMENT IF NOT VOLATILE
102     *
103     *  reset tx, channel a
104     *  reset rx, channel a
105     *  reset mr pointer, ch
106     */
107     MC68681_WRITE(DUART_ADDR, MC68681_COMMAND_REG_A, MC68681_MODE_REG_RESET_TX);
108     MC68681_WRITE(DUART_ADDR, MC68681_COMMAND_REG_A, MC68681_MODE_REG_RESET_RX);
109     MC68681_WRITE(DUART_ADDR, MC68681_COMMAND_REG_A, MC68681_MODE_REG_RESET_MR_PTR);
110
111     Pit_initialized = 1;
112  }
113
114  /*
115   * Init the general registers of the duart
116   *
117   * init ivr
118   * init imr
119   * init acr
120   * init ctur
121   * init ctlr
122   * init opcr
123   * init cts
124   */
125  MC68681_WRITE(DUART_ADDR, MC68681_INTERRUPT_VECTOR_REG, 
126                MC68681_INTERRUPT_VECTOR_INIT);
127  MC68681_WRITE(DUART_ADDR, MC68681_INTERRUPT_MASK_REG,
128                MC68681_IR_RX_READY_A | MC68681_IR_RX_READY_B); 
129  MC68681_WRITE(DUART_ADDR, MC68681_AUX_CTRL_REG, MC68681_CLEAR);
130  MC68681_WRITE(DUART_ADDR, MC68681_COUNTER_TIMER_UPPER_REG, 0x00);
131  MC68681_WRITE(DUART_ADDR, MC68681_COUNTER_TIMER_LOWER_REG, 0x02);
132  MC68681_WRITE(DUART_ADDR, MC68681_OUTPUT_PORT_CONFIG_REG, MC68681_CLEAR);
133  MC68681_WRITE(DUART_ADDR, MC68681_OUTPUT_PORT_SET_REG, 0x01);
134
135  /*
136   * init the actual serial port for port a
137   *
138   * Set Baud Rate to 9600
139   * Set Stop bit length of 1
140   * enable Transmit and receive
141   */
142  MC68681_WRITE(DUART_ADDR, MC68681_CLOCK_SELECT_REG_A, MC68681_BAUD_RATE_MASK_9600);
143  MC68681_WRITE(DUART_ADDR, MC68681_MODE_REG_1A,
144                (MC68681_8BIT_CHARS | MC68681_NO_PARITY));
145  MC68681_WRITE(DUART_ADDR, MC68681_MODE_REG_2A,MC68681_STOP_BIT_LENGTH_1);
146  MC68681_WRITE(DUART_ADDR, MC68681_COMMAND_REG_A,
147                (MC68681_MODE_REG_ENABLE_TX | MC68681_MODE_REG_ENABLE_RX));
148
149  /*
150   * init the actual serial port for port b
151   * init csrb -- 9600 baud
152   */
153  MC68681_WRITE(DUART_ADDR, MC68681_CLOCK_SELECT_REG_B, MC68681_BAUD_RATE_MASK_9600);
154
155
156#define EIGHT_BITS_NO_PARITY
157#ifdef EIGHT_BITS_NO_PARITY
158  /*
159   * Set 8 Bit characters with no parity
160   */
161  MC68681_WRITE(DUART_ADDR, MC68681_MODE_REG_1B,
162                (MC68681_NO_PARITY | MC68681_8BIT_CHARS) );
163#else
164  /*
165   * Set 7 Bit Characters with parity
166   */
167  MC68681_WRITE(DUART_ADDR, MC68681_MODE_REG_1B,
168                (MC68681_WITH_PARITY |  MC68681_7BIT_CHARS) );
169#endif
170
171
172  /*
173   * Set Stop Bit length to 1
174   * Disable Recieve and transmit on B
175   */
176  MC68681_WRITE(DUART_ADDR, MC68681_MODE_REG_2B,MC68681_STOP_BIT_LENGTH_1);
177  MC68681_WRITE(DUART_ADDR, MC68681_COMMAND_REG_B,
178                (MC68681_MODE_REG_ENABLE_TX | MC68681_MODE_REG_ENABLE_RX) );
179}
180
181/*#####################################################################
182# interrupt handler for receive of character from duart on ports A & B
183#####################################################################*/
184rtems_isr C_Receive_ISR(rtems_vector_number vector)
185{
186  volatile unsigned char *_addr;
187
188  /*
189   *  Clear pit interrupt.
190   */
191  _addr = (unsigned char *) (PIT_ADDR + PITSR);
192  *_addr = 0x04;
193
194  /*
195   *  check port A first for input
196   *     extract rcvrdy on port B
197   *     set ptr to recieve buffer and read character into ring buffer
198   */
199  _addr = (unsigned char *) (DUART_ADDR + MC68681_STATUS_REG_A);
200  if (*_addr & MC68681_RX_READY)  /* extract rcvrdy on port A */
201  {
202    _addr = (unsigned char *) (DUART_ADDR + MC68681_RECEIVE_BUFFER_A);
203    Ring_buffer_Add_character( &Buffer[ 0 ], *_addr );
204  }
205
206  /*
207   *  If not on port A, let's check port B
208   *     extract rcvrdy on port B
209   *     set ptr to recieve buffer and read character into ring buffer
210   */
211  else
212  {
213    _addr = (unsigned char *) (DUART_ADDR + MC68681_STATUS_REG_B);
214    if (*_addr & MC68681_RX_READY)  /* extract rcvrdy on port B */
215    {
216      _addr = (unsigned char *) (DUART_ADDR + MC68681_RECEIVE_BUFFER_B);
217      Ring_buffer_Add_character( &Buffer[ 1 ], *_addr );
218    }
219
220    /*
221     * if not ready on port A or port B, must be an error
222     * if error, get out so that fifo is undisturbed
223     */
224  }
225}
226
227/*#####################################################################
228# This is the routine that actually transmits a character one at a time
229# This routine transmits on port A of the IDP board
230#####################################################################*/
231void transmit_char(char ch)
232{
233  volatile unsigned char *_addr;
234
235  /*
236   * Get SRA (extract txrdy)
237   */
238  _addr = (unsigned char *) (DUART_ADDR + MC68681_STATUS_REG_A);
239  while (!(*_addr & MC68681_TX_READY))
240  {
241  }
242
243  /*
244   * transmit character over port A
245   */
246  MC68681_WRITE(DUART_ADDR, MC68681_TRANSMIT_BUFFER_A, ch);
247}
248
249
250/*#####################################################################
251# This is the routine that actually transmits a character one at a time
252# This routine transmits on port B of the IDP board
253#####################################################################*/
254void transmit_char_portb(char ch)
255{
256  volatile unsigned char *_addr;
257
258  /*
259   * Get SRB (extract txrdy)
260   */
261  _addr = (unsigned char *) (DUART_ADDR + MC68681_STATUS_REG_B);
262  while (!(*_addr &  MC68681_TX_READY))
263  {
264  }
265
266  /*
267   * transmit character over port B
268   */
269  MC68681_WRITE(DUART_ADDR, MC68681_TRANSMIT_BUFFER_B, ch);
270}
Note: See TracBrowser for help on using the repository browser.