diff options
Diffstat (limited to 'bsps/m68k/gen68340/console/m340uart.c')
-rw-r--r-- | bsps/m68k/gen68340/console/m340uart.c | 311 |
1 files changed, 311 insertions, 0 deletions
diff --git a/bsps/m68k/gen68340/console/m340uart.c b/bsps/m68k/gen68340/console/m340uart.c new file mode 100644 index 0000000000..56ad29c256 --- /dev/null +++ b/bsps/m68k/gen68340/console/m340uart.c @@ -0,0 +1,311 @@ +/* + * M68340/349 UART management tools + */ + +/* + * Author: + * Geoffroy Montel + * France Telecom - CNET/DSM/TAM/CAT + * 4, rue du Clos Courtel + * 35512 CESSON-SEVIGNE + * FRANCE + * + * e-mail: g_montel@yahoo.com + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include <termios.h> +#include <bsp.h> +#include <rtems/libio.h> +#include <m68340.h> +#include <m340uart.h> +#include <stdarg.h> +#include <string.h> + +/* this table shows compatible speed configurations for the MC68340: + the first row shows baud rates for baud speed set 1 + the second row shows baud rates for baud speed set 2 + look at Motorola's MC68340 Integrated Processor User's Manual + page 7-30 for more infos */ + +float m340_Baud_Rates_Table[16][2] = { + { 50, 75 }, + { 110, 110 }, + { 134.5, 134.5 }, + { 200, 150 }, + { 300, 300 }, + { 600, 600 }, + { 1200, 1200 }, + { 1050, 2000 }, + { 2400, 2400 }, + { 4800, 4800 }, + { 7200, 1800 }, + { 9600, 9600 }, + { 38400, 19200 }, + { 76800, 38400 }, + { SCLK/16, SCLK/16}, + { SCLK, SCLK }, +}; + +/* config on both 340 channels */ +uart_channel_config m340_uart_config[UART_NUMBER_OF_CHANNELS]; + +/* + * Init UART table + */ + +#define NOT_IMPLEMENTED_YET 0 + +/****************************************************** + Name: Init_UART_Table + Input parameters: - + Output parameters: - + Description: Init the m340_uart_config + THIS SHOULD NOT BE HERE! + Its aim was to let the user configure + UARTs for each application. + As we can't pass args to the console + driver initialisation routine at the + moment, this was not done. + ATTENTION: TERMIOS init presupposes that the channel + baud rates is 9600/9600. + -> risks when using IOCTL + *****************************************************/ +void Init_UART_Table(void) +{ + m340_uart_config[UART_CHANNEL_A].enable = TRUE; + strcpy(m340_uart_config[UART_CHANNEL_A].name, UART_CONSOLE_NAME); + m340_uart_config[UART_CHANNEL_A].parity_mode = m340_No_Parity; + m340_uart_config[UART_CHANNEL_A].bits_per_char = m340_8bpc; + m340_uart_config[UART_CHANNEL_A].rx_baudrate = 9600; + m340_uart_config[UART_CHANNEL_A].tx_baudrate = 9600; + m340_uart_config[UART_CHANNEL_A].rx_mode = UART_CRR; + m340_uart_config[UART_CHANNEL_A].mode = UART_POLLING; + + m340_uart_config[UART_CHANNEL_A].termios.enable = TRUE; + m340_uart_config[UART_CHANNEL_A].termios.rx_buffer_size = NOT_IMPLEMENTED_YET; + m340_uart_config[UART_CHANNEL_A].termios.tx_buffer_size = NOT_IMPLEMENTED_YET; + + m340_uart_config[UART_CHANNEL_B].enable = FALSE; + strcpy(m340_uart_config[UART_CHANNEL_B].name, UART_RAW_IO_NAME); + m340_uart_config[UART_CHANNEL_B].parity_mode = m340_No_Parity; + m340_uart_config[UART_CHANNEL_B].bits_per_char = m340_8bpc; + m340_uart_config[UART_CHANNEL_B].rx_baudrate = 38400; + m340_uart_config[UART_CHANNEL_B].tx_baudrate = 38400; + m340_uart_config[UART_CHANNEL_B].rx_mode = UART_CRR; + m340_uart_config[UART_CHANNEL_B].mode = UART_INTERRUPTS; + + m340_uart_config[UART_CHANNEL_B].termios.enable = TRUE; + m340_uart_config[UART_CHANNEL_B].termios.rx_buffer_size = NOT_IMPLEMENTED_YET; + m340_uart_config[UART_CHANNEL_B].termios.tx_buffer_size = NOT_IMPLEMENTED_YET; +} + +/****************************************************** + Name: Find_Right_m340_UART_Channel_Config + Input parameters: Send/Receive baud rates for a + given channel + Output parameters: UART compatible configs for this + channel + Description: returns which uart configurations fit + Receiver Baud Rate and Transmitter Baud + Rate for a given channel + For instance, according to the + m340_Baud_Rates_Table: + - Output Speed = 50, Input Speed = 75 + is not a correct config, because + 50 bauds implies set 1 and 75 bauds + implies set 2 + - Output Speed = 9600, Input Speed = 9600 + two correct configs for this: + RCS=11, TCS=11, Set=1 or 2 + *****************************************************/ +static t_baud_speed_table +Find_Right_m340_UART_Channel_Config( + float ReceiverBaudRate, + float TransmitterBaudRate +) +{ + t_baud_speed_table return_value; + int i,j; + + struct { + int cs; + int set; + } Receiver[2], Transmitter[2]; + + int Receiver_nb_of_config = 0; + int Transmitter_nb_of_config = 0; + + /* Receiver and Transmitter baud rates must be compatible, ie in the + * same set. + */ + + /* search for configurations for ReceiverBaudRate + * there can't be more than two (only two sets). + */ + for (i=0;i<16;i++) { + for (j=0;j<2;j++) { + if (m340_Baud_Rates_Table[i][j]==ReceiverBaudRate) { + Receiver[Receiver_nb_of_config].cs=i; + Receiver[Receiver_nb_of_config].set=j; + Receiver_nb_of_config++; + } + } + } + + /* search for configurations for TransmitterBaudRate + * there can't be more than two (only two sets) + */ + for (i=0;i<16;i++) { + for (j=0;j<2;j++) { + if (m340_Baud_Rates_Table[i][j]==TransmitterBaudRate) { + Transmitter[Transmitter_nb_of_config].cs=i; + Transmitter[Transmitter_nb_of_config].set=j; + Transmitter_nb_of_config++; + } + } + } + + /* now check if there's a compatible config */ + return_value.nb=0; + + for (i=0; i<Receiver_nb_of_config; i++) { + for (j=0;j<Transmitter_nb_of_config;j++) { + if (Receiver[i].set == Transmitter[j].set) { + return_value.baud_speed_table[return_value.nb].set = Receiver[i].set + 1; + /* we want set 1 or set 2, not 0 or 1 */ + return_value.baud_speed_table[return_value.nb].rcs = Receiver[i].cs; + return_value.baud_speed_table[return_value.nb].tcs = Transmitter[j].cs; + return_value.nb++; + } + } + } + + return return_value; +} + +/****************************************************** + Name: Find_Right_m340_UART_Config + Input parameters: Send/Receive baud rates for both + channels + Output parameters: UART compatible configs for + BOTH channels + Description: returns which uart configurations fit + Receiver Baud Rate and Transmitter Baud + Rate for both channels + For instance, if we want 9600/38400 on + channel A and 9600/19200 on channel B, + this is not a good m340 uart config + (channel A needs set 1 and channel B + needs set 2) + *****************************************************/ +t_baud_speed_table +Find_Right_m340_UART_Config( + float ChannelA_ReceiverBaudRate, + float ChannelA_TransmitterBaudRate, + uint8_t enableA, + float ChannelB_ReceiverBaudRate, + float ChannelB_TransmitterBaudRate, + uint8_t enableB +) +{ + t_baud_speed_table tableA, tableB; + t_baud_speed_table return_value, tmp; + int i,j; + + memset( &return_value, '\0', sizeof(return_value) ); + return_value.nb=0; + + if (enableA && enableB) { + tableA = Find_Right_m340_UART_Channel_Config( + ChannelA_ReceiverBaudRate, ChannelA_TransmitterBaudRate); + tableB = Find_Right_m340_UART_Channel_Config( + ChannelB_ReceiverBaudRate, ChannelB_TransmitterBaudRate); + + for (i=0;i<tableA.nb;i++) { + for (j=0;j<tableB.nb;j++) { + if (tableA.baud_speed_table[i].set==tableB.baud_speed_table[j].set) { + return_value.baud_speed_table[UART_CHANNEL_A].set = + tableA.baud_speed_table[i].set; + return_value.baud_speed_table[UART_CHANNEL_A].rcs = + tableA.baud_speed_table[i].rcs; + return_value.baud_speed_table[UART_CHANNEL_A].tcs = + tableA.baud_speed_table[i].tcs; + return_value.baud_speed_table[UART_CHANNEL_B].set = + tableB.baud_speed_table[j].set; + return_value.baud_speed_table[UART_CHANNEL_B].rcs = + tableB.baud_speed_table[j].rcs; + return_value.baud_speed_table[UART_CHANNEL_B].tcs = + tableB.baud_speed_table[j].tcs; + return_value.nb=2; + break; + } + } + } + return return_value; + } + + if (enableA) { + return_value = Find_Right_m340_UART_Channel_Config( + ChannelA_ReceiverBaudRate, ChannelA_TransmitterBaudRate); + return return_value; + } + + if (enableB) { + tmp = Find_Right_m340_UART_Channel_Config( + ChannelB_ReceiverBaudRate, ChannelB_TransmitterBaudRate); + if (tmp.nb!=0) { + return_value.nb = 2; + return_value.baud_speed_table[1].set = tmp.baud_speed_table[0].set; + return_value.baud_speed_table[1].rcs = tmp.baud_speed_table[0].rcs; + return_value.baud_speed_table[1].tcs = tmp.baud_speed_table[0].tcs; + } + } + return return_value; +} + + +/* + * very low level fmted output + */ +extern void dbug_out_char( int minor, int ch ); +extern int dbug_in_char( int minor ); +extern int dbug_char_present( int minor ); + +/****************************************************** + Name: dbugRead + Input parameters: channel + Output parameters: char read + Description: polled read + *****************************************************/ +int dbugRead (int minor) +{ + if (dbug_char_present(minor) == 0) + return -1; + return dbug_in_char(minor); +} + +/****************************************************** + Name: dbugWrite + Input parameters: channel, buffer and its length + Output parameters: always successfull + Description: polled write + *****************************************************/ +ssize_t dbugWrite (int minor, const char *buf, size_t len) +{ + static char txBuf; + size_t retval = len; + + while (len--) { + txBuf = *buf++; + dbug_out_char( minor, (int)txBuf ); + } + return retval; +} + |