source: rtems/c/src/lib/libbsp/m68k/gen68340/console/m340uart.c @ 08b5f55

4.104.114.84.95
Last change on this file since 08b5f55 was 132f194, checked in by Joel Sherrill <joel.sherrill@…>, on Jul 1, 1998 at 10:03:20 PM

Initial submission of gen68340 BSP (should run on a 68349) from
Geoffroy Montel <g_montel@…>.

  • Property mode set to 100644
File size: 12.3 KB
Line 
1/*
2 *  M68340/349 uart management tools
3 *
4 *  Author:
5 *  Geoffroy Montel
6 *  France Telecom - CNET/DSM/TAM/CAT
7 *  4, rue du Clos Courtel
8 *  35512 CESSON-SEVIGNE
9 *  FRANCE
10 *
11 *  e-mail: g_montel@yahoo.com
12 *
13 *  COPYRIGHT (c) 1989-1998.
14 *  On-Line Applications Research Corporation (OAR).
15 *  Copyright assigned to U.S. Government, 1994.
16 *
17 *  The license and distribution terms for this file may be
18 *  found in the file LICENSE in this distribution or at
19 *
20 *  http://www.OARcorp.com/rtems/license.html.
21 *
22 *  $Id$
23 */
24
25#include <termios.h>
26#include <bsp.h>
27#include <rtems/libio.h>
28#include <m68340.h>
29#include <m340uart.h>
30#include <stdarg.h>
31
32/* this table shows compatible speed configurations for the MC68340:
33   the first row shows baud rates for baud speed set 1
34   the second row shows baud rates for baud speed set 2
35   look at Motorola's MC68340 Integrated Processor User's Manual
36   page 7-30 for more infos */
37
38float m340_Baud_Rates_Table[16][2] = {\
39      { 50,    75       },   \
40      { 110,   110      },   \
41      { 134.5, 134.5    },   \
42      { 200,   150      },   \
43      { 300,   300      },   \
44      { 600,   600      },   \
45      { 1200,  1200     },   \
46      { 1050,  2000     },   \
47      { 2400,  2400     },   \
48      { 4800,  4800     },   \
49      { 7200,  1800     },   \
50      { 9600,  9600     },   \
51      { 38400, 19200    },   \
52      { 76800, 38400    },   \
53      { SCLK/16, SCLK/16},   \
54      { SCLK,  SCLK     },   \
55};
56
57/* config on both 340 channels */
58uart_channel_config m340_uart_config[UART_NUMBER_OF_CHANNELS];
59
60/*
61 * Init UART table
62 */
63
64#define NOT_IMPLEMENTED_YET 0
65
66/******************************************************
67  Name: Init_UART_Table
68  Input parameters: -
69  Output parameters: -
70  Description: Init the m340_uart_config
71               THIS SHOULD NOT BE HERE!
72               Its aim was to let the user configure
73               UARTs for each application.
74               As we can't pass args to the console
75               driver initialisation routine at the
76               moment, this was not done.
77  ATTENTION: TERMIOS init presupposes that the channel
78             baud rates is 9600/9600.
79             -> risks when using IOCTL
80 *****************************************************/
81void Init_UART_Table(void)
82{
83 m340_uart_config[UART_CHANNEL_A].enable = TRUE;
84 strcpy(m340_uart_config[UART_CHANNEL_A].name, UART_CONSOLE_NAME);
85 m340_uart_config[UART_CHANNEL_A].parity_mode = m340_No_Parity;
86 m340_uart_config[UART_CHANNEL_A].bits_per_char = m340_8bpc;
87 m340_uart_config[UART_CHANNEL_A].rx_baudrate = 9600;
88 m340_uart_config[UART_CHANNEL_A].tx_baudrate = 9600;
89 m340_uart_config[UART_CHANNEL_A].rx_mode = UART_CRR;
90 m340_uart_config[UART_CHANNEL_A].mode = UART_POLLING;
91
92 m340_uart_config[UART_CHANNEL_A].termios.enable = TRUE;
93 m340_uart_config[UART_CHANNEL_A].termios.rx_buffer_size = NOT_IMPLEMENTED_YET;
94 m340_uart_config[UART_CHANNEL_A].termios.tx_buffer_size = NOT_IMPLEMENTED_YET;
95
96 m340_uart_config[UART_CHANNEL_B].enable = FALSE;
97 strcpy(m340_uart_config[UART_CHANNEL_B].name, UART_RAW_IO_NAME);
98 m340_uart_config[UART_CHANNEL_B].parity_mode = m340_No_Parity;
99 m340_uart_config[UART_CHANNEL_B].bits_per_char = m340_8bpc;
100 m340_uart_config[UART_CHANNEL_B].rx_baudrate = 38400;
101 m340_uart_config[UART_CHANNEL_B].tx_baudrate = 38400;
102 m340_uart_config[UART_CHANNEL_B].rx_mode = UART_CRR;
103 m340_uart_config[UART_CHANNEL_B].mode = UART_INTERRUPTS;
104
105 m340_uart_config[UART_CHANNEL_B].termios.enable = TRUE;
106 m340_uart_config[UART_CHANNEL_B].termios.rx_buffer_size = NOT_IMPLEMENTED_YET;
107 m340_uart_config[UART_CHANNEL_B].termios.tx_buffer_size = NOT_IMPLEMENTED_YET;
108}
109
110/******************************************************
111  Name: Find_Right_m340_UART_Channel_Config
112  Input parameters: Send/Receive baud rates for a
113                    given channel
114  Output parameters: UART compatible configs for this
115                    channel
116  Description: returns which uart configurations fit
117               Receiver Baud Rate and Transmitter Baud
118               Rate for a given channel
119               For instance, according to the
120               m340_Baud_Rates_Table:
121               - Output Speed = 50, Input Speed = 75
122                 is not a correct config, because
123                 50 bauds implies set 1 and 75 bauds
124                 implies set 2
125               - Output Speed = 9600, Input Speed = 9600
126                 two correct configs for this:
127                 RCS=11, TCS=11, Set=1 or 2
128 *****************************************************/
129t_baud_speed_table
130Find_Right_m340_UART_Channel_Config(float ReceiverBaudRate, float TransmitterBaudRate)
131{
132 t_baud_speed_table return_value;
133
134 struct {
135         int cs;
136         int set;
137        } Receiver[2], Transmitter[2];
138
139 int Receiver_nb_of_config = 0;
140 int Transmitter_nb_of_config = 0;
141
142 int i,j;
143
144 /* Receiver and Transmitter baud rates must be compatible, ie in the same set */
145 
146 /* search for configurations for ReceiverBaudRate - there can't be more than two (only two sets) */
147 for (i=0;i<16;i++)
148     for (j=0;j<2;j++)
149         if (m340_Baud_Rates_Table[i][j]==ReceiverBaudRate) {
150            Receiver[Receiver_nb_of_config].cs=i;
151            Receiver[Receiver_nb_of_config].set=j;
152            Receiver_nb_of_config++;
153         }
154 
155 /* search for configurations for TransmitterBaudRate - there can't be more than two (only two sets) */
156 for (i=0;i<16;i++)
157     for (j=0;j<2;j++)
158         if (m340_Baud_Rates_Table[i][j]==TransmitterBaudRate) {
159            Transmitter[Transmitter_nb_of_config].cs=i;
160            Transmitter[Transmitter_nb_of_config].set=j;
161            Transmitter_nb_of_config++;
162         }
163
164 /* now check if there's a compatible config */ 
165 return_value.nb=0;
166 
167 for (i=0; i<Receiver_nb_of_config; i++)
168     for (j=0;j<Transmitter_nb_of_config;j++)
169         if (Receiver[i].set == Transmitter[j].set) {
170            return_value.baud_speed_table[return_value.nb].set = Receiver[i].set + 1; /* we want set 1 or set 2, not 0 or 1 */
171            return_value.baud_speed_table[return_value.nb].rcs = Receiver[i].cs;
172            return_value.baud_speed_table[return_value.nb].tcs = Transmitter[j].cs;         
173            return_value.nb++;
174         }
175
176 return return_value;
177}
178
179/******************************************************
180  Name: Find_Right_m340_UART_Config
181  Input parameters: Send/Receive baud rates for both
182                    channels
183  Output parameters: UART compatible configs for
184                     BOTH channels
185  Description: returns which uart configurations fit
186               Receiver Baud Rate and Transmitter Baud
187               Rate for both channels
188               For instance, if we want 9600/38400 on
189               channel A and 9600/19200 on channel B,
190               this is not a good m340 uart config
191               (channel A needs set 1 and channel B
192               needs set 2)
193 *****************************************************/
194t_baud_speed_table
195Find_Right_m340_UART_Config(float ChannelA_ReceiverBaudRate, float ChannelA_TransmitterBaudRate, rtems_unsigned8 enableA,
196                            float ChannelB_ReceiverBaudRate, float ChannelB_TransmitterBaudRate, rtems_unsigned8 enableB)
197{
198 t_baud_speed_table tableA, tableB;
199 t_baud_speed_table return_value, tmp;
200 int i,j;
201
202 return_value.nb=0;
203
204 if (enableA && enableB) {
205  tableA = Find_Right_m340_UART_Channel_Config(ChannelA_ReceiverBaudRate, ChannelA_TransmitterBaudRate);
206  tableB = Find_Right_m340_UART_Channel_Config(ChannelB_ReceiverBaudRate, ChannelB_TransmitterBaudRate);
207
208  for (i=0;i<tableA.nb;i++)
209      for (j=0;j<tableB.nb;j++)
210          if (tableA.baud_speed_table[i].set==tableB.baud_speed_table[j].set) {
211             return_value.baud_speed_table[UART_CHANNEL_A].set=tableA.baud_speed_table[i].set;
212             return_value.baud_speed_table[UART_CHANNEL_A].rcs=tableA.baud_speed_table[i].rcs;
213             return_value.baud_speed_table[UART_CHANNEL_A].tcs=tableA.baud_speed_table[i].tcs;
214             return_value.baud_speed_table[UART_CHANNEL_B].set=tableB.baud_speed_table[j].set;
215             return_value.baud_speed_table[UART_CHANNEL_B].rcs=tableB.baud_speed_table[j].rcs;
216             return_value.baud_speed_table[UART_CHANNEL_B].tcs=tableB.baud_speed_table[j].tcs;
217             return_value.nb=2;
218             break;
219          }
220   return return_value;
221 }
222
223 if (enableA) {
224    return_value = Find_Right_m340_UART_Channel_Config(ChannelA_ReceiverBaudRate, ChannelA_TransmitterBaudRate);
225    return return_value;
226 }
227
228 if (enableB) {
229    tmp = Find_Right_m340_UART_Channel_Config(ChannelB_ReceiverBaudRate, ChannelB_TransmitterBaudRate);
230    if (tmp.nb!=0) {
231       return_value.nb = 2;
232       return_value.baud_speed_table[1].set = tmp.baud_speed_table[0].set;
233       return_value.baud_speed_table[1].rcs = tmp.baud_speed_table[0].rcs;
234       return_value.baud_speed_table[1].tcs = tmp.baud_speed_table[0].tcs;
235    }
236 }
237 return return_value;
238}
239
240/******************************************************
241  Name: termios_baud_rates_equivalence
242  Input parameters: Termios coded speed
243  Output parameters: explicit speed
244  Description: ioctl calls return termios coded speed
245               we need to know real speed in order
246               to use the functions above
247 *****************************************************/
248float termios_baud_rates_equivalence ( int speed ) 
249{
250 switch (speed) {
251        default:        return 0;       break;
252        case B50:       return 50;      break;
253        case B75:       return 75;      break;
254        case B110:      return 110;     break;
255        case B134:      return 134;     break;
256        case B150:      return 150;     break;
257        case B200:      return 200;     break;
258        case B300:      return 300;     break;
259        case B600:      return 600;     break;
260        case B1200:     return 1200;    break;
261        case B1800:     return 1800;    break;
262        case B2400:     return 2400;    break;
263        case B4800:     return 4800;    break;
264        case B9600:     return 9600;    break;
265        case B19200:    return 19200;   break;
266        case B38400:    return 38400;   break;
267        case B57600:    return 57600;   break;
268        case B115200:   return 115200;  break;
269        case B230400:   return 230400;  break;
270        case B460800:   return 460800;  break;
271 }
272 return 0;
273}
274
275/****************************************************************************************************/
276
277/*
278 * very low level fmted output
279 */
280
281extern void dbug_out_char( int minor, int ch );
282extern int dbug_in_char( int minor );
283extern int dbug_char_present( int minor );
284
285/******************************************************
286  Name: dbugRead
287  Input parameters: channel
288  Output parameters: char read
289  Description: polled read
290 *****************************************************/
291int dbugRead (int minor)
292{
293        if (dbug_char_present(minor) == 0)
294                return -1;
295        return dbug_in_char(minor);
296}
297
298/******************************************************
299  Name: dbugWrite
300  Input parameters: channel, buffer and its length
301  Output parameters: always successfull
302  Description: polled write
303 *****************************************************/
304int dbugWrite (int minor, const char *buf, int len)
305{
306        static char txBuf;
307       
308        while (len--) {
309                txBuf = *buf++;
310                dbug_out_char( minor, (int)txBuf );
311        }
312        return 0;
313}
314
315static void fmt_num( int minor, unsigned long, unsigned );
316static void fmt_str( int minor, const char* );
317
318/******************************************************
319  Name: RAW_GETC
320  Input parameters: channel, buffer and its length
321  Output parameters:
322  Description: a light blocking "getc"
323 *****************************************************/
324char RAW_GETC(int minor)
325{
326 while (!dbug_char_present(minor)) continue;
327 return dbug_in_char(minor);
328}
329
330/******************************************************
331  Name: RAW_FMT
332  Input parameters: channel, buffer and its length
333  Output parameters: always successfull
334  Description: a light polled "printf"
335               useful when there's a serious pb and
336               there are no more interrupts
337 *****************************************************/
338void RAW_FMT( int minor, const char* fmt, ... )
339{
340   int ch;
341   va_list va;
342
343   va_start( va, fmt );
344
345   while( (ch = *fmt++) )
346      if( ch != '%' || (ch = *fmt++) == '%' )
347      {
348         if( ch == '\n' )
349            dbug_out_char( minor, '\r' );
350         dbug_out_char( minor, ch );
351      }
352      else switch( ch )
353      {
354         case 'c':
355         dbug_out_char( minor, va_arg( va, int ) );
356         continue;
357         case 's':
358         fmt_str( minor, va_arg( va, char* ) );
359         continue;
360         case 'd':
361         ch = va_arg( va, int );
362         if( ch >= 0 )
363            fmt_num( minor, ch, 10 );
364         else
365         {
366            dbug_out_char( minor, '-' );
367            fmt_num( minor, -ch, 10 );
368         }
369         continue;
370         case 'u':
371         fmt_num( minor, va_arg( va, unsigned ), 10 );
372         continue;
373         case 'o':
374         fmt_num( minor, va_arg( va, unsigned ), 8 );
375         continue;
376         case 'x':
377         case 'p':
378         fmt_num( minor, va_arg( va, unsigned ), 16 );
379         continue;
380         default: continue;
381         return;
382      }
383   va_end( va );
384}
385
386static void fmt_num( int minor, unsigned long num, unsigned base )
387{
388   char buf[33];
389   int  ib = sizeof(buf);
390
391   buf[--ib] = 0;
392   do
393   {
394      buf[--ib] = "0123456789ABCDEF"[num%base];
395      num /= base;
396   }
397   while( num != 0 );
398
399   fmt_str( minor, buf+ib );
400}
401
402static void fmt_str( int minor, const char* str )
403{
404   if( str )
405      while( *str )
406         dbug_out_char( minor, *str++ );
407}
408
409
Note: See TracBrowser for help on using the repository browser.