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

4.115
Last change on this file since 3785ed6c was c499856, checked in by Chris Johns <chrisj@…>, on 03/20/14 at 21:10:47

Change all references of rtems.com to rtems.org.

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