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

4.104.114.84.95
Last change on this file since d7aecdc was 08311cc3, checked in by Joel Sherrill <joel.sherrill@…>, on 11/17/99 at 17:51:34

Updated copyright notice.

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