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

4.104.114.95
Last change on this file since 0c04063b was 0c04063b, checked in by Joel Sherrill <joel.sherrill@…>, on 05/23/08 at 15:48:06

2008-05-23 Joel Sherrill <joel.sherrill@…>

  • console/m340uart.c: Eliminate copies of switches to convert termios Bxxx constants to xxx as an integer. Use the shared termios_baud_to_number() routine to do the same conversion.
  • Property mode set to 100644
File size: 11.2 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.rtems.com/license/LICENSE.
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#include <string.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, uint8_t         enableA,
196                            float ChannelB_ReceiverBaudRate, float ChannelB_TransmitterBaudRate, uint8_t         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
242/*
243 * very low level fmted output
244 */
245
246extern void dbug_out_char( int minor, int ch );
247extern int dbug_in_char( int minor );
248extern int dbug_char_present( int minor );
249
250/******************************************************
251  Name: dbugRead
252  Input parameters: channel
253  Output parameters: char read
254  Description: polled read
255 *****************************************************/
256int dbugRead (int minor)
257{
258        if (dbug_char_present(minor) == 0)
259                return -1;
260        return dbug_in_char(minor);
261}
262
263/******************************************************
264  Name: dbugWrite
265  Input parameters: channel, buffer and its length
266  Output parameters: always successfull
267  Description: polled write
268 *****************************************************/
269int dbugWrite (int minor, const char *buf, int len)
270{
271        static char txBuf;
272
273        while (len--) {
274                txBuf = *buf++;
275                dbug_out_char( minor, (int)txBuf );
276        }
277        return 0;
278}
279
280static void fmt_num( int minor, unsigned long, unsigned );
281static void fmt_str( int minor, const char* );
282
283/******************************************************
284  Name: RAW_GETC
285  Input parameters: channel, buffer and its length
286  Output parameters:
287  Description: a light blocking "getc"
288 *****************************************************/
289char RAW_GETC(int minor)
290{
291 while (!dbug_char_present(minor)) continue;
292 return dbug_in_char(minor);
293}
294
295/******************************************************
296  Name: RAW_FMT
297  Input parameters: channel, buffer and its length
298  Output parameters: always successfull
299  Description: a light polled "printf"
300               useful when there's a serious pb and
301               there are no more interrupts
302 *****************************************************/
303void RAW_FMT( int minor, const char* fmt, ... )
304{
305   int ch;
306   va_list va;
307
308   va_start( va, fmt );
309
310   while( (ch = *fmt++) )
311      if( ch != '%' || (ch = *fmt++) == '%' )
312      {
313         if( ch == '\n' )
314            dbug_out_char( minor, '\r' );
315         dbug_out_char( minor, ch );
316      }
317      else switch( ch )
318      {
319         case 'c':
320         dbug_out_char( minor, va_arg( va, int ) );
321         continue;
322         case 's':
323         fmt_str( minor, va_arg( va, char* ) );
324         continue;
325         case 'd':
326         ch = va_arg( va, int );
327         if( ch >= 0 )
328            fmt_num( minor, ch, 10 );
329         else
330         {
331            dbug_out_char( minor, '-' );
332            fmt_num( minor, -ch, 10 );
333         }
334         continue;
335         case 'u':
336         fmt_num( minor, va_arg( va, unsigned ), 10 );
337         continue;
338         case 'o':
339         fmt_num( minor, va_arg( va, unsigned ), 8 );
340         continue;
341         case 'x':
342         case 'p':
343         fmt_num( minor, va_arg( va, unsigned ), 16 );
344         continue;
345         default: continue;
346         return;
347      }
348   va_end( va );
349}
350
351static void fmt_num( int minor, unsigned long num, unsigned base )
352{
353   char buf[33];
354   int  ib = sizeof(buf);
355
356   buf[--ib] = 0;
357   do
358   {
359      buf[--ib] = "0123456789ABCDEF"[num%base];
360      num /= base;
361   }
362   while( num != 0 );
363
364   fmt_str( minor, buf+ib );
365}
366
367static void fmt_str( int minor, const char* str )
368{
369   if( str )
370      while( *str )
371         dbug_out_char( minor, *str++ );
372}
Note: See TracBrowser for help on using the repository browser.