Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:45

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  *  M68340/349 UART management tools
0005  */
0006 
0007 /*
0008  *  Author:
0009  *  Geoffroy Montel
0010  *  France Telecom - CNET/DSM/TAM/CAT
0011  *  4, rue du Clos Courtel
0012  *  35512 CESSON-SEVIGNE
0013  *  FRANCE
0014  *
0015  *  e-mail: g_montel@yahoo.com
0016  *
0017  *  COPYRIGHT (c) 1989-1999.
0018  *  On-Line Applications Research Corporation (OAR).
0019  *
0020  * Redistribution and use in source and binary forms, with or without
0021  * modification, are permitted provided that the following conditions
0022  * are met:
0023  * 1. Redistributions of source code must retain the above copyright
0024  *    notice, this list of conditions and the following disclaimer.
0025  * 2. Redistributions in binary form must reproduce the above copyright
0026  *    notice, this list of conditions and the following disclaimer in the
0027  *    documentation and/or other materials provided with the distribution.
0028  *
0029  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0030  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0031  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0032  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0033  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0034  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0035  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0036  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0037  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0038  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0039  * POSSIBILITY OF SUCH DAMAGE.
0040  */
0041 
0042 #include <termios.h>
0043 #include <bsp.h>
0044 #include <rtems/libio.h>
0045 #include <m68340.h>
0046 #include <m340uart.h>
0047 #include <stdarg.h>
0048 #include <string.h>
0049 
0050 /* this table shows compatible speed configurations for the MC68340:
0051    the first row shows baud rates for baud speed set 1
0052    the second row shows baud rates for baud speed set 2
0053    look at Motorola's MC68340 Integrated Processor User's Manual
0054    page 7-30 for more infos */
0055 
0056 float m340_Baud_Rates_Table[16][2] = {
0057       { 50,    75 },
0058       { 110,   110 },
0059       { 134.5, 134.5 },
0060       { 200,   150 },
0061       { 300,   300 },
0062       { 600,   600 },
0063       { 1200,  1200 },
0064       { 1050,  2000 },
0065       { 2400,  2400 },
0066       { 4800,  4800 },
0067       { 7200,  1800 },
0068       { 9600,  9600 },
0069       { 38400, 19200 },
0070       { 76800, 38400 },
0071       { SCLK/16, SCLK/16},
0072       { SCLK,  SCLK },
0073 };
0074 
0075 /* config on both 340 channels */
0076 uart_channel_config m340_uart_config[UART_NUMBER_OF_CHANNELS];
0077 
0078 /*
0079  * Init UART table
0080  */
0081 
0082 #define NOT_IMPLEMENTED_YET 0
0083 
0084 /******************************************************
0085   Name: Init_UART_Table
0086   Input parameters: -
0087   Output parameters: -
0088   Description: Init the m340_uart_config
0089          THIS SHOULD NOT BE HERE!
0090          Its aim was to let the user configure
0091          UARTs for each application.
0092          As we can't pass args to the console
0093          driver initialisation routine at the
0094          moment, this was not done.
0095   ATTENTION: TERMIOS init presupposes that the channel
0096        baud rates is 9600/9600.
0097        -> risks when using IOCTL
0098  *****************************************************/
0099 void Init_UART_Table(void)
0100 {
0101   m340_uart_config[UART_CHANNEL_A].enable = TRUE;
0102   strcpy(m340_uart_config[UART_CHANNEL_A].name, UART_CONSOLE_NAME);
0103   m340_uart_config[UART_CHANNEL_A].parity_mode = m340_No_Parity;
0104   m340_uart_config[UART_CHANNEL_A].bits_per_char = m340_8bpc;
0105   m340_uart_config[UART_CHANNEL_A].rx_baudrate = 9600;
0106   m340_uart_config[UART_CHANNEL_A].tx_baudrate = 9600;
0107   m340_uart_config[UART_CHANNEL_A].rx_mode = UART_CRR;
0108   m340_uart_config[UART_CHANNEL_A].mode = UART_POLLING;
0109 
0110   m340_uart_config[UART_CHANNEL_A].termios.enable = TRUE;
0111   m340_uart_config[UART_CHANNEL_A].termios.rx_buffer_size = NOT_IMPLEMENTED_YET;
0112   m340_uart_config[UART_CHANNEL_A].termios.tx_buffer_size = NOT_IMPLEMENTED_YET;
0113 
0114   m340_uart_config[UART_CHANNEL_B].enable = FALSE;
0115   strcpy(m340_uart_config[UART_CHANNEL_B].name, UART_RAW_IO_NAME);
0116   m340_uart_config[UART_CHANNEL_B].parity_mode = m340_No_Parity;
0117   m340_uart_config[UART_CHANNEL_B].bits_per_char = m340_8bpc;
0118   m340_uart_config[UART_CHANNEL_B].rx_baudrate = 38400;
0119   m340_uart_config[UART_CHANNEL_B].tx_baudrate = 38400;
0120   m340_uart_config[UART_CHANNEL_B].rx_mode = UART_CRR;
0121   m340_uart_config[UART_CHANNEL_B].mode = UART_INTERRUPTS;
0122 
0123   m340_uart_config[UART_CHANNEL_B].termios.enable = TRUE;
0124   m340_uart_config[UART_CHANNEL_B].termios.rx_buffer_size = NOT_IMPLEMENTED_YET;
0125   m340_uart_config[UART_CHANNEL_B].termios.tx_buffer_size = NOT_IMPLEMENTED_YET;
0126 }
0127 
0128 /******************************************************
0129   Name: Find_Right_m340_UART_Channel_Config
0130   Input parameters: Send/Receive baud rates for a
0131         given channel
0132   Output parameters: UART compatible configs for this
0133         channel
0134   Description: returns which uart configurations fit
0135          Receiver Baud Rate and Transmitter Baud
0136          Rate for a given channel
0137          For instance, according to the
0138          m340_Baud_Rates_Table:
0139                - Output Speed = 50, Input Speed = 75
0140      is not a correct config, because
0141      50 bauds implies set 1 and 75 bauds
0142      implies set 2
0143                - Output Speed = 9600, Input Speed = 9600
0144      two correct configs for this:
0145      RCS=11, TCS=11, Set=1 or 2
0146  *****************************************************/
0147 static t_baud_speed_table
0148 Find_Right_m340_UART_Channel_Config(
0149   float ReceiverBaudRate,
0150   float TransmitterBaudRate
0151 )
0152 {
0153   t_baud_speed_table return_value;
0154   int i,j;
0155 
0156   struct {
0157     int cs;
0158     int set;
0159   } Receiver[2], Transmitter[2];
0160 
0161   int Receiver_nb_of_config = 0;
0162   int Transmitter_nb_of_config = 0;
0163 
0164   /* Receiver and Transmitter baud rates must be compatible, ie in the
0165    * same set.
0166    */
0167 
0168   /* search for configurations for ReceiverBaudRate
0169    * there can't be more than two (only two sets).
0170    */
0171   for (i=0;i<16;i++) {
0172     for (j=0;j<2;j++) {
0173       if (m340_Baud_Rates_Table[i][j]==ReceiverBaudRate) {
0174         Receiver[Receiver_nb_of_config].cs=i;
0175         Receiver[Receiver_nb_of_config].set=j;
0176         Receiver_nb_of_config++;
0177       }
0178     }
0179   }
0180 
0181   /* search for configurations for TransmitterBaudRate
0182    * there can't be more than two (only two sets)
0183    */
0184   for (i=0;i<16;i++) {
0185     for (j=0;j<2;j++) {
0186       if (m340_Baud_Rates_Table[i][j]==TransmitterBaudRate) {
0187         Transmitter[Transmitter_nb_of_config].cs=i;
0188         Transmitter[Transmitter_nb_of_config].set=j;
0189         Transmitter_nb_of_config++;
0190       }
0191     }
0192   }
0193 
0194   /* now check if there's a compatible config */
0195   return_value.nb=0;
0196 
0197  for (i=0; i<Receiver_nb_of_config; i++) {
0198    for (j=0;j<Transmitter_nb_of_config;j++) {
0199      if (Receiver[i].set == Transmitter[j].set) {
0200        return_value.baud_speed_table[return_value.nb].set = Receiver[i].set + 1;
0201        /* we want set 1 or set 2, not 0 or 1 */
0202        return_value.baud_speed_table[return_value.nb].rcs = Receiver[i].cs;
0203        return_value.baud_speed_table[return_value.nb].tcs = Transmitter[j].cs;
0204        return_value.nb++;
0205      }
0206    }
0207  }
0208 
0209  return return_value;
0210 }
0211 
0212 /******************************************************
0213   Name: Find_Right_m340_UART_Config
0214   Input parameters: Send/Receive baud rates for both
0215         channels
0216   Output parameters: UART compatible configs for
0217          BOTH channels
0218   Description: returns which uart configurations fit
0219          Receiver Baud Rate and Transmitter Baud
0220          Rate for both channels
0221          For instance, if we want 9600/38400 on
0222          channel A and 9600/19200 on channel B,
0223          this is not a good m340 uart config
0224          (channel A needs set 1 and channel B
0225          needs set 2)
0226  *****************************************************/
0227 t_baud_speed_table
0228 Find_Right_m340_UART_Config(
0229   float ChannelA_ReceiverBaudRate,
0230   float ChannelA_TransmitterBaudRate,
0231   uint8_t         enableA,
0232   float ChannelB_ReceiverBaudRate,
0233   float ChannelB_TransmitterBaudRate,
0234   uint8_t         enableB
0235 )
0236 {
0237   t_baud_speed_table tableA, tableB;
0238   t_baud_speed_table return_value, tmp;
0239   int i,j;
0240 
0241   memset( &return_value, '\0', sizeof(return_value) );
0242   return_value.nb=0;
0243 
0244   if (enableA && enableB) {
0245     tableA = Find_Right_m340_UART_Channel_Config(
0246                ChannelA_ReceiverBaudRate, ChannelA_TransmitterBaudRate);
0247     tableB = Find_Right_m340_UART_Channel_Config(
0248                ChannelB_ReceiverBaudRate, ChannelB_TransmitterBaudRate);
0249 
0250     for (i=0;i<tableA.nb;i++) {
0251       for (j=0;j<tableB.nb;j++) {
0252         if (tableA.baud_speed_table[i].set==tableB.baud_speed_table[j].set) {
0253           return_value.baud_speed_table[UART_CHANNEL_A].set =
0254             tableA.baud_speed_table[i].set;
0255           return_value.baud_speed_table[UART_CHANNEL_A].rcs =
0256             tableA.baud_speed_table[i].rcs;
0257           return_value.baud_speed_table[UART_CHANNEL_A].tcs =
0258             tableA.baud_speed_table[i].tcs;
0259           return_value.baud_speed_table[UART_CHANNEL_B].set =
0260             tableB.baud_speed_table[j].set;
0261           return_value.baud_speed_table[UART_CHANNEL_B].rcs =
0262             tableB.baud_speed_table[j].rcs;
0263           return_value.baud_speed_table[UART_CHANNEL_B].tcs =
0264             tableB.baud_speed_table[j].tcs;
0265           return_value.nb=2;
0266           break;
0267         }
0268       }
0269     }
0270     return return_value;
0271   }
0272 
0273   if (enableA) {
0274     return_value = Find_Right_m340_UART_Channel_Config(
0275           ChannelA_ReceiverBaudRate, ChannelA_TransmitterBaudRate);
0276     return return_value;
0277   }
0278 
0279   if (enableB) {
0280     tmp = Find_Right_m340_UART_Channel_Config(
0281       ChannelB_ReceiverBaudRate, ChannelB_TransmitterBaudRate);
0282     if (tmp.nb!=0) {
0283       return_value.nb = 2;
0284       return_value.baud_speed_table[1].set = tmp.baud_speed_table[0].set;
0285       return_value.baud_speed_table[1].rcs = tmp.baud_speed_table[0].rcs;
0286       return_value.baud_speed_table[1].tcs = tmp.baud_speed_table[0].tcs;
0287     }
0288   }
0289   return return_value;
0290 }
0291 
0292 
0293 /*
0294  * very low level fmted output
0295  */
0296 extern void dbug_out_char( int minor, int ch );
0297 extern int dbug_in_char( int minor );
0298 extern int dbug_char_present( int minor );
0299 
0300 /******************************************************
0301   Name: dbugRead
0302   Input parameters: channel
0303   Output parameters: char read
0304   Description: polled read
0305  *****************************************************/
0306 int dbugRead (int minor)
0307 {
0308   if (dbug_char_present(minor) == 0)
0309     return -1;
0310   return dbug_in_char(minor);
0311 }
0312 
0313 /******************************************************
0314   Name: dbugWrite
0315   Input parameters: channel, buffer and its length
0316   Output parameters: always successfull
0317   Description: polled write
0318  *****************************************************/
0319 ssize_t dbugWrite (int minor, const char *buf, size_t len)
0320 {
0321   static char txBuf;
0322   size_t retval = len;
0323 
0324   while (len--) {
0325      txBuf = *buf++;
0326           dbug_out_char( minor, (int)txBuf );
0327   }
0328   return retval;
0329 }
0330