summaryrefslogtreecommitdiffstats
path: root/tools/cpu/sh/sci.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--tools/cpu/sh/sci.c157
1 files changed, 157 insertions, 0 deletions
diff --git a/tools/cpu/sh/sci.c b/tools/cpu/sh/sci.c
new file mode 100644
index 0000000000..58be0e68bf
--- /dev/null
+++ b/tools/cpu/sh/sci.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 1998 Ralf Corsepius (corsepiu@faw.uni-ulm.de)
+ *
+ * See the file COPYING for copyright notice.
+ */
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "sci.h"
+
+/*
+ n .. baudrate generator source 0,1,2,3
+
+ N .. BRR setting (0..255)
+
+ Phi .. processor baud rate
+
+ B .. bitrate
+ */
+
+typedef struct sci_tab {
+ unsigned int B ;
+ unsigned int n ;
+ int N ;
+ double err ;
+ } sci_tab_t ;
+
+static unsigned int bitrate [] = {
+ 50,
+ 75,
+ 110,
+ 134,
+ 150,
+ 200,
+ 300,
+ 600,
+ 1200,
+ 1800,
+ 2400,
+ 4800,
+ 9600,
+ 19200,
+ 38400,
+ 57600,
+ 115200,
+ 230400,
+ 460800
+};
+
+static sci_tab_t test_array[4] ;
+
+static void Compute(
+ unsigned int n,
+ unsigned int B,
+ unsigned int Phi,
+ struct sci_tab *entry )
+{
+ int a = ( 32 << ( 2 * n ) ) * B ;
+
+ entry->n = n ;
+ entry->B = B ;
+ entry->N = rint( ( Phi / a ) - 1.0 ) ;
+
+ if ( ( entry->N > 0 ) && ( entry->N < 256 ) )
+ entry->err =
+ ( ( Phi / ( (entry->N + 1) * a ) - 1.0 ) * 100.0 );
+ else
+ entry->err = 100.0 ;
+}
+
+static sci_tab_t *SelectN(
+ unsigned int B,
+ double Phi )
+{
+ unsigned int i ;
+ struct sci_tab* best = NULL ;
+
+ for ( i = 0 ; i < 4 ; i++ )
+ {
+ double err ;
+
+ Compute( i, B, Phi, &test_array[i] );
+ err = fabs( test_array[i].err );
+
+ if ( best )
+ {
+ if ( err < fabs( best->err ) )
+ best = &test_array[i] ;
+ }
+ else
+ best = &test_array[i] ;
+ }
+
+ return best ;
+}
+
+int shgen_gensci(
+ FILE *file,
+ double Phi ) /* Processor frequency [Hz] */
+{
+ unsigned int i ;
+
+ fprintf( file,
+ "/*\n * Bitrate table for the serial devices (sci) of the SH at %.3f MHz\n"
+ " */\n\n", Phi / 1000000.0 );
+ fprintf( file,
+ "/*\n"
+ " * n .. SMR bits 0,1 : baud rate generator clock source\n"
+ " * N .. BRR bits 0..7: setting for baud rate generator\n"
+ " * error .. percentual error to nominal bitrate\n"
+ " * Hitachi's HW manual recommends bitrates with an error less than 1%%\n"
+ " * We experienced values less than 2%% to be stable\n"
+ " */\n\n" );
+ fprintf( file, "#include <termios.h>\n\n" );
+ fprintf( file,
+ "static struct sci_bitrate_t {\n"
+ " unsigned char n ;\n"
+ " unsigned char N ;\n"
+ "} _sci_bitrates[] = {\n"
+ "/* n N error */\n" );
+
+ for ( i = 0 ; i < sizeof(bitrate)/sizeof(int) ; i++ )
+ {
+ struct sci_tab* best = SelectN( bitrate[i], Phi );
+
+ if ( i > 0 )
+ fprintf( file, ",\n" );
+ fprintf( file, " { %1d, %3d } /* %+7.2f%% ; B%d */",
+ best->n,
+ best->N,
+ best->err,
+ best->B );
+ }
+
+ fprintf( file, "\n};\n\n" );
+
+ fprintf( file,
+ "int _sci_get_brparms( \n"
+ " tcflag_t cflag,\n"
+ " unsigned char *smr,\n"
+ " unsigned char *brr )\n"
+ "{\n"
+ " unsigned int offset ;\n\n"
+ " offset = ( cflag & ( CBAUD & ~CBAUDEX ) )\n"
+ " + ( ( cflag & CBAUDEX ) ? B38400 : 0 );\n"
+ " if ( offset == 0 ) return -1 ;\n"
+ " offset-- ;\n\n"
+ " *smr &= ~0x03;\n"
+ " *smr |= _sci_bitrates[offset].n;\n"
+ " *brr = _sci_bitrates[offset].N;\n\n"
+ " return 0;\n"
+ "}\n" );
+
+ return 0 ;
+}